*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <linux/errno.h>
-
-/*
- * Chip Specific Head File
- */
+#include <asm/danube/danube.h>
#include <asm/danube/port.h>
-
#include <asm/danube/danube_led.h>
#include <asm/danube/danube_gptu.h>
+#define LED_CONFIG 0x01
+
+#define CONFIG_OPERATION_UPDATE_SOURCE 0x0001
+#define CONFIG_OPERATION_BLINK 0x0002
+#define CONFIG_OPERATION_UPDATE_CLOCK 0x0004
+#define CONFIG_OPERATION_STORE_MODE 0x0008
+#define CONFIG_OPERATION_SHIFT_CLOCK 0x0010
+#define CONFIG_OPERATION_DATA_OFFSET 0x0020
+#define CONFIG_OPERATION_NUMBER_OF_LED 0x0040
+#define CONFIG_OPERATION_DATA 0x0080
+#define CONFIG_OPERATION_MIPS0_ACCESS 0x0100
+#define CONFIG_DATA_CLOCK_EDGE 0x0200
+
+
+/*
+* Data Type Used to Call ioctl
+*/
+struct led_config_param {
+ unsigned long operation_mask; // Select operations to be performed
+ unsigned long led; // LED to change update source (LED or ADSL)
+ unsigned long source; // Corresponding update source (LED or ADSL)
+ unsigned long blink_mask; // LEDs to set blink mode
+ unsigned long blink; // Set to blink mode or normal mode
+ unsigned long update_clock; // Select the source of update clock
+ unsigned long fpid; // If FPI is the source of update clock, set the divider
+ // else if GPT is the source, set the frequency
+ unsigned long store_mode; // Set clock mode or single pulse mode for store signal
+ unsigned long fpis; // FPI is the source of shift clock, set the divider
+ unsigned long data_offset; // Set cycles to be inserted before data is transmitted
+ unsigned long number_of_enabled_led; // Total number of LED to be enabled
+ unsigned long data_mask; // LEDs to set value
+ unsigned long data; // Corresponding value
+ unsigned long mips0_access_mask; // LEDs to set access right
+ unsigned long mips0_access; // 1: the corresponding data is output from MIPS0, 0: MIPS1
+ unsigned long f_data_clock_on_rising; // 1: data clock on rising edge, 0: data clock on falling edge
+};
-/*
- * ####################################
- * Definition
- * ####################################
- */
-#define DEBUG_ON_AMAZON 0
+extern int danube_led_set_blink(unsigned int, unsigned int);
+extern int danube_led_set_data(unsigned int, unsigned int);
+extern int danube_led_config(struct led_config_param *);
#define DATA_CLOCKING_EDGE FALLING_EDGE
-
-#define BOARD_TYPE REFERENCE_BOARD
-
-#define DEBUG_WRITE_REGISTER 0
-
#define RISING_EDGE 0
#define FALLING_EDGE 1
-#define EVALUATION_BOARD 0
-#define REFERENCE_BOARD 1
-
-/*
- * GPIO Driver Function Wrapping
- */
#define port_reserve_pin danube_port_reserve_pin
#define port_free_pin danube_port_free_pin
#define port_set_altsel0 danube_port_set_altsel0
#define port_set_open_drain danube_port_set_open_drain
#define port_clear_open_drain danube_port_clear_open_drain
-/*
- * GPIO Port Used By LED
- */
#define LED_SH_PORT 0
#define LED_SH_PIN 4
#define LED_SH_DIR 1
#define ADSL_LED_IS_EXCLUSIVE 0
#endif
-/*
- * Define GPIO Functions
- */
#if LED_SH_DIR
#define LED_SH_DIR_SETUP port_set_dir_out
#else
#define LED_ADSL1_OPENDRAIN_SETUP port_clear_open_drain
#endif
-/*
- * LED Device Minor Number
- */
-#if !defined(LED_MINOR)
- #define LED_MINOR 151 // This number is written in Linux kernel document "devices.txt"
-#endif // !defined(LED_MINOR)
-
-/*
- * Bits Operation
- */
-#define GET_BITS(x, msb, lsb) (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
#define SET_BITS(x, msb, lsb, value) (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
-/*
- * LED Registers Mapping
- */
-#define DANUBE_LED (KSEG1 + 0x1E100BB0)
-#define DANUBE_LED_CON0 ((volatile u32*)(DANUBE_LED + 0x0000))
-#define DANUBE_LED_CON1 ((volatile u32*)(DANUBE_LED + 0x0004))
-#define DANUBE_LED_CPU0 ((volatile u32*)(DANUBE_LED + 0x0008))
-#define DANUBE_LED_CPU1 ((volatile u32*)(DANUBE_LED + 0x000C))
-#define DANUBE_LED_AR ((volatile u32*)(DANUBE_LED + 0x0010))
-
-/*
- * LED Control 0 Register
- */
-#define LED_CON0_SWU (*DANUBE_LED_CON0 & (1 << 31))
-#define LED_CON0_FALLING_EDGE (*DANUBE_LED_CON0 & (1 << 26))
-#define LED_CON0_AD1 (*DANUBE_LED_CON0 & (1 << 25))
-#define LED_CON0_AD0 (*DANUBE_LED_CON0 & (1 << 24))
-#define LED_CON0_LBn(n) (*DANUBE_LED_CON0 & (1 << n))
-#define LED_CON0_DEFAULT_VALUE (0x80000000 | (DATA_CLOCKING_EDGE << 26))
-
-/*
- * LED Control 1 Register
- */
-#define LED_CON1_US (*DANUBE_LED_CON1 >> 30)
-#define LED_CON1_SCS (*DANUBE_LED_CON1 & (1 << 28))
-#define LED_CON1_FPID GET_BITS(*DANUBE_LED_CON1, 27, 23)
-#define LED_CON1_FPIS GET_BITS(*DANUBE_LED_CON1, 21, 20)
-#define LED_CON1_DO GET_BITS(*DANUBE_LED_CON1, 19, 18)
-#define LED_CON1_G2 (*DANUBE_LED_CON1 & (1 << 2))
-#define LED_CON1_G1 (*DANUBE_LED_CON1 & (1 << 1))
-#define LED_CON1_G0 (*DANUBE_LED_CON1 & 0x01)
-#define LED_CON1_G (*DANUBE_LED_CON1 & 0x07)
-#define LED_CON1_DEFAULT_VALUE 0x00000000
-
-/*
- * LED Data Output CPU 0 Register
- */
-#define LED_CPU0_Ln(n) (*DANUBE_LED_CPU0 & (1 << n))
-#define LED_LED_CPU0_DEFAULT_VALUE 0x00000000
-
-/*
- * LED Data Output CPU 1 Register
- */
-#define LED_CPU1_Ln(n) (*DANUBE_LED_CPU1 & (1 << n))
-#define LED_LED_CPU1_DEFAULT_VALUE 0x00000000
-
-/*
- * LED Data Output Access Rights Register
- */
-#define LED_AR_Ln(n) (*DANUBE_LED_AR & (1 << n))
-#define LED_AR_DEFAULT_VALUE 0x00000000
-
-
-/*
- * ####################################
- * Preparation of Debug on Amazon Chip
- * ####################################
- */
-
-/*
- * If try module on Amazon chip, prepare some tricks to prevent invalid memory write.
- */
-#if defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON
- char g_pFakeRegisters[0x50];
-
- #undef DEBUG_WRITE_REGISTER
-
- #undef DANUBE_LED
- #define DANUBE_LED g_pFakeRegisters
-
- #undef port_reserve_pin
- #undef port_free_pin
- #undef port_set_altsel0
- #undef port_clear_altsel0
- #undef port_set_altsel1
- #undef port_clear_altsel1
- #undef port_set_dir_out
-
- #define port_reserve_pin amazon_port_reserve_pin
- #define port_free_pin amazon_port_free_pin
- #define port_set_altsel0 amazon_port_set_altsel0
- #define port_clear_altsel0 amazon_port_clear_altsel0
- #define port_set_altsel1 amazon_port_set_altsel1
- #define port_clear_altsel1 amazon_port_clear_altsel1
- #define port_set_dir_out amazon_port_set_dir_out
-#endif // defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON
-
-
-/*
- * ####################################
- * Declaration
- * ####################################
- */
-
-/*
- * File Operations
- */
-static int led_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-static int led_open(struct inode *, struct file *);
-static int led_release(struct inode *, struct file *);
-
-/*
- * Software Update LED
- */
static inline int update_led(void);
-/*
- * LED Configuration Functions
- */
-static inline u32 set_update_source(u32, unsigned long, unsigned long);
-static inline u32 set_blink_in_batch(u32, unsigned long, unsigned long);
-static inline u32 set_data_clock_edge(u32, unsigned long);
-static inline u32 set_update_clock(u32, unsigned long, unsigned long);
-static inline u32 set_store_mode(u32, unsigned long);
-static inline u32 set_shift_clock(u32, unsigned long);
-static inline u32 set_data_offset(u32, unsigned long);
-static inline u32 set_number_of_enabled_led(u32, unsigned long);
-static inline u32 set_data_in_batch(u32, unsigned long, unsigned long);
-static inline u32 set_access_right(u32, unsigned long, unsigned long);
+static inline unsigned int set_update_source(unsigned int, unsigned long, unsigned long);
+static inline unsigned int set_blink_in_batch(unsigned int, unsigned long, unsigned long);
+static inline unsigned int set_data_clock_edge(unsigned int, unsigned long);
+static inline unsigned int set_update_clock(unsigned int, unsigned long, unsigned long);
+static inline unsigned int set_store_mode(unsigned int, unsigned long);
+static inline unsigned int set_shift_clock(unsigned int, unsigned long);
+static inline unsigned int set_data_offset(unsigned int, unsigned long);
+static inline unsigned int set_number_of_enabled_led(unsigned int, unsigned long);
+static inline unsigned int set_data_in_batch(unsigned int, unsigned long, unsigned long);
+static inline unsigned int set_access_right(unsigned int, unsigned long, unsigned long);
-/*
- * PMU Operation
- */
static inline void enable_led(void);
static inline void disable_led(void);
-/*
- * GPIO Setup & Release
- */
static inline int setup_gpio_port(unsigned long);
static inline void release_gpio_port(unsigned long);
-/*
- * GPT Setup & Release
- */
static inline int setup_gpt(int, unsigned long);
static inline void release_gpt(int);
-/*
- * Turn On/Off LED
- */
static inline int turn_on_led(unsigned long);
static inline void turn_off_led(unsigned long);
-/*
- * ####################################
- * Local Variable
- * ####################################
- */
-
static struct semaphore led_sem;
-static struct file_operations led_fops = {
- owner: THIS_MODULE,
- ioctl: led_ioctl,
- open: led_open,
- release: led_release
-};
-
-static struct miscdevice led_miscdev = {
- LED_MINOR,
- "led",
- &led_fops,
- NULL,
- NULL,
- NULL
-};
-
static unsigned long gpt_on = 0;
static unsigned long gpt_freq = 0;
static int module_id;
-/*
- * ####################################
- * Global Variable
- * ####################################
- */
-
-
-/*
- * ####################################
- * Local Function
- * ####################################
- */
-
-static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret = -EINVAL;
- struct led_config_param param;
-
- switch ( cmd )
- {
- case LED_CONFIG:
- copy_from_user(¶m, (char*)arg, sizeof(param));
- ret = danube_led_config(¶m);
- break;
- }
-
- return ret;
-}
-
-static int led_open(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static int led_release(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-/*
- * Description:
- * Update LEDs with data stored in register.
- * Input:
- * none
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-static inline int update_led(void)
+static inline int
+update_led (void)
{
int i, j;
/*
* GPT2 or FPID is the clock to update LEDs automatically.
*/
- if ( LED_CON1_US != 0 )
+ if (readl(DANUBE_LED_CON1) >> 30)
return 0;
/*
for ( i = 100000; i != 0; i -= j / 16 )
{
down(&led_sem);
- if ( !LED_CON0_SWU )
+ if (!(readl(DANUBE_LED_CON0) & LED_CON0_SWU))
{
*DANUBE_LED_CON0 |= 1 << 31;
up(&led_sem);
return -EBUSY;
}
-/*
- * Description:
- * Select update source for LED bit 0 and bit 1.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * led --- unsigned long, bit 0 stands for LED 0, and bit 1 stands for
- * LED 1. If the bit is set, the source value is valid, else
- * the source value is invalid.
- * source --- unsigned long, bit 0 stands for LED 0, and bit 1 stands for
- * LED 1. If the corresponding is cleared, LED is updated with
- * value in data register, else LED is updated with ARC module.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_update_source(u32 reg, unsigned long led, unsigned long source)
+static inline unsigned int
+set_update_source (unsigned int reg, unsigned long led, unsigned long source)
{
return (reg & ~((led & 0x03) << 24)) | ((source & 0x03) << 24);
}
-/*
- * Description:
- * Define which of the LEDs should change their value based on the US pulse.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * mask --- unsigned long, if the corresponding bit is set, the blink value
- * is valid, else the blink value is invalid.
- * blink --- unsigned long, if the corresponding bit is set, the LED should
- * change its value based on the US pulse.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_blink_in_batch(u32 reg, unsigned long mask, unsigned long blink)
+static inline unsigned int
+set_blink_in_batch (unsigned int reg, unsigned long mask, unsigned long blink)
{
return (reg & (~(mask & 0x00FFFFFF) & 0x87FFFFFF)) | (blink & 0x00FFFFFF);
}
-static inline u32 set_data_clock_edge(u32 reg, unsigned long f_on_rising_edge)
+static inline unsigned int
+set_data_clock_edge (unsigned int reg, unsigned long f_on_rising_edge)
{
return f_on_rising_edge ? (reg & ~(1 << 26)) : (reg | (1 << 26));
}
-/*
- * Description:
- * Select the clock source for US pulse.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * clock --- unsigned long, there 3 available values:
- * 0x00 - use software update bit (SWU) as source.
- * 0x01 - use GPT2 as clock source.
- * 0x02 - use FPI as clock source.
- * fpid --- unsigned long, if FPI is selected as clock source, this field
- * specify the divider. Please refer to specification for detail
- * description.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_update_clock(u32 reg, unsigned long clock, unsigned long fpid)
+static inline unsigned int
+set_update_clock (unsigned int reg, unsigned long clock, unsigned long fpid)
{
switch ( clock )
{
return reg;
}
-/*
- * Description:
- * Set the behavior of the LED_ST (shift register) signal.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * mode --- unsigned long, there 2 available values:
- * zero - LED controller generate single pulse.
- * non-zero - LED controller generate inverted shift clock.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_store_mode(u32 reg, unsigned long mode)
+static inline unsigned int
+set_store_mode (unsigned int reg, unsigned long mode)
{
return mode ? (reg | (1 << 28)) : (reg & ~(1 << 28));
}
-/*
- * Description:
- * Select the clock source for shift clock LED_SH.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * fpis --- unsigned long, if FPI is selected as clock source, this field
- * specify the divider. Please refer to specification for detail
- * description.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_shift_clock(u32 reg, unsigned long fpis)
+static inline
+unsigned int set_shift_clock (unsigned int reg, unsigned long fpis)
{
return SET_BITS(reg, 21, 20, fpis);
}
-/*
- * Description:
- * Set the clock cycle offset before data is transmitted to LED_D pin.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * offset --- unsigned long, the number of clock cycles would be inserted
- * before data is transmitted to LED_D pin. Zero means no cycle
- * inserted.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_data_offset(u32 reg, unsigned long offset)
+static inline
+unsigned int set_data_offset (unsigned int reg, unsigned long offset)
{
return SET_BITS(reg, 19, 18, offset);
}
-/*
- * Description:
- * Enable or disable LEDs.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * number --- unsigned long, the number of LED to be enabled. This field
- * could 0, 8, 16 or 24. Zero means disable all LEDs.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_number_of_enabled_led(u32 reg, unsigned long number)
+static inline
+unsigned int set_number_of_enabled_led (unsigned int reg, unsigned long number)
{
- u32 bit_mask;
+ unsigned int bit_mask;
bit_mask = number > 16 ? 0x07 : (number > 8 ? 0x03 : (number ? 0x01 : 0x00));
return (reg & ~0x07) | bit_mask;
}
-/*
- * Description:
- * Turn on/off LEDs.
- * Input:
- * reg --- u32, the original register value going to be modified.
- * mask --- unsigned long, if the corresponding bit is set, the data value
- * is valid, else the data value is invalid.
- * data --- unsigned long, if the corresponding bit is set, the LED should
- * be on, else be off.
- * Output:
- * u32 --- The updated register value.
- */
-static inline u32 set_data_in_batch(u32 reg, unsigned long mask, unsigned long data)
+static inline unsigned int
+set_data_in_batch (unsigned int reg, unsigned long mask, unsigned long data)
{
return (reg & ~(mask & 0x00FFFFFF)) | (data & 0x00FFFFFF);
}
-static inline u32 set_access_right(u32 reg, unsigned long mask, unsigned long ar)
+static inline unsigned int
+set_access_right (unsigned int reg, unsigned long mask, unsigned long ar)
{
return (reg & ~(mask & 0x00FFFFFF)) | (~ar & mask);
}
-/*
- * Description:
- * Enable LED control module.
- * Input:
- * none
- * Output:
- * none
- */
-static inline void enable_led(void)
+static inline void
+enable_led (void)
{
-#if !defined(DEBUG_ON_AMAZON) || !DEBUG_ON_AMAZON
/* Activate LED module in PMU. */
int i = 1000000;
while ( --i && (*(unsigned long *)0xBF102020 & (1 << 11)) );
if ( !i )
panic("Activating LED in PMU failed!");
-#endif
}
-/*
- * Description:
- * Disable LED control module.
- * Input:
- * none
- * Output:
- * none
- */
-static inline void disable_led(void)
+static inline void
+disable_led (void)
{
-#if !defined(DEBUG_ON_AMAZON) || !DEBUG_ON_AMAZON
- /* Inactivating LED module in PMU. */
*(unsigned long *)0xBF10201C |= 1 << 11;
-#endif
}
-/*
- * Description:
- * If LEDs are enabled, GPIO must be setup to enable LED pins.
- * Input:
- * none
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-static inline int setup_gpio_port(unsigned long adsl)
+static inline int
+setup_gpio_port (unsigned long adsl)
{
-#if !defined(DEBUG_ON_AMAZON) || !DEBUG_ON_AMAZON
int ret = 0;
- #if defined(DEBUG_WRITE_REGISTER) && DEBUG_WRITE_REGISTER
- if ( adsl )
- {
- *(unsigned long *)0xBE100B18 |= 0x30;
- *(unsigned long *)0xBE100B1C |= 0x20;
- *(unsigned long *)0xBE100B1C &= ~0x10;
- *(unsigned long *)0xBE100B20 |= 0x30;
- *(unsigned long *)0xBE100B24 |= 0x30;
- }
- else
- {
- *(unsigned long *)0xBE100B18 |= 0x70;
- *(unsigned long *)0xBE100B1C |= 0x70;
- *(unsigned long *)0xBE100B20 &= ~0x70;
- *(unsigned long *)0xBE100B24 |= 0x70;
- }
- #else
-
/*
* Reserve all pins before config them.
*/
LED_SH_DIR_SETUP(LED_SH_PORT, LED_SH_PIN, module_id);
LED_SH_OPENDRAIN_SETUP(LED_SH_PORT, LED_SH_PIN, module_id);
}
- #endif
-#endif
return 0;
}
-/*
- * Description:
- * If LEDs are all disabled, GPIO must be released so that other application
- * could reuse it.
- * Input:
- * none
- * Output:
- * none
- */
-static inline void release_gpio_port(unsigned long adsl)
+static inline void
+release_gpio_port (unsigned long adsl)
{
-#if !defined(DEBUG_ON_AMAZON) || !DEBUG_ON_AMAZON
- #if !defined(DEBUG_WRITE_REGISTER) || !DEBUG_WRITE_REGISTER
if ( adsl )
{
port_free_pin(LED_ADSL0_PORT, LED_ADSL0_PIN, module_id);
port_free_pin(LED_D_PORT, LED_D_PIN, module_id);
port_free_pin(LED_SH_PORT, LED_SH_PIN, module_id);
}
- #endif
-#endif
}
-/*
- * Description:
- * If shifter or update select GPT as clock source, this function would be
- * invoked to setup corresponding GPT module.
- * Attention please, this function is not working since the GPTU driver is
- * not ready.
- * Input:
- * timer --- int, index of timer.
- * freq --- unsigned long, frequency of timer (0.001Hz). This value will be
- * rounded off to nearest possible value.
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-static inline int setup_gpt(int timer, unsigned long freq)
+static inline int
+setup_gpt (int timer, unsigned long freq)
{
int ret;
-#if 0
- timer = TIMER(timer, 0);
-#else
- timer = TIMER(timer, 1); // 2B
-#endif
+ timer = TIMER(timer, 1);
-#if 0
- ret = set_timer(timer, freq, 1, 0, TIMER_FLAG_NO_HANDLE, 0, 0);
-#else
ret = request_timer(timer,
TIMER_FLAG_SYNC
| TIMER_FLAG_16BIT
0,
0);
-#endif
-// printk("setup_gpt: timer = %d, freq = %d, return = %d\n", timer, freq, ret);
if ( !ret )
{
ret = start_timer(timer, 0);
return ret;
}
-/*
- * Description:
- * If shifter or update select other clock source, allocated GPT must be
- * released so that other application can use it.
- * Attention please, this function is not working since the GPTU driver is
- * not ready.
- * Input:
- * none
- * Output:
- * none
- */
-static inline void release_gpt(int timer)
+static inline void
+release_gpt (int timer)
{
-#if 0
- timer = TIMER(timer, 0);
-#else
timer = TIMER(timer, 1);
-#endif
stop_timer(timer);
free_timer(timer);
}
-static inline int turn_on_led(unsigned long adsl)
+static inline int
+turn_on_led (unsigned long adsl)
{
int ret;
return 0;
}
-static inline void turn_off_led(unsigned long adsl)
+static inline void
+turn_off_led (unsigned long adsl)
{
release_gpio_port(adsl);
disable_led();
}
-/*
- * ####################################
- * Global Function
- * ####################################
- */
-
-/*
- * Description:
- * Define which of the LEDs should change its value based on the US pulse.
- * Input:
- * led --- unsigned int, index of the LED to be set.
- * blink --- unsigned int, zero means normal mode, and non-zero means blink
- * mode.
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-int danube_led_set_blink(unsigned int led, unsigned int blink)
+int
+danube_led_set_blink (unsigned int led, unsigned int blink)
{
- u32 bit_mask;
+ unsigned int bit_mask;
if ( led > 23 )
return -EINVAL;
*DANUBE_LED_CON0 &= ~bit_mask;
up(&led_sem);
- return (led == 0 && LED_CON0_AD0) || (led == 1 && LED_CON0_AD1) ? -EINVAL : 0;
+ return (led == 0 && (readl(DANUBE_LED_CON0) & LED_CON0_AD0)) || (led == 1 && (readl(DANUBE_LED_CON0) & LED_CON0_AD1)) ? -EINVAL : 0;
}
-/*
- * Description:
- * Turn on/off LED.
- * Input:
- * led --- unsigned int, index of the LED to be set.
- * data --- unsigned int, zero means off, and non-zero means on.
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-int danube_led_set_data(unsigned int led, unsigned int data)
+int
+danube_led_set_data (unsigned int led, unsigned int data)
{
unsigned long f_update;
- u32 bit_mask;
+ unsigned int bit_mask;
if ( led > 23 )
return -EINVAL;
return f_update ? update_led() : 0;
}
-/*
- * Description:
- * Config LED controller.
- * Input:
- * param --- struct led_config_param*, the members are listed below:
- * operation_mask - Select operations to be performed
- * led - LED to change update source
- * source - Corresponding update source
- * blink_mask - LEDs to set blink mode
- * blink - Set to blink mode or normal mode
- * update_clock - Select the source of update clock
- * fpid - If FPI is the source of update clock, set the divider
- * store_mode - Set clock mode or single pulse mode for store signal
- * fpis - If FPI is the source of shift clock, set the divider
- * data_offset - Set cycles to be inserted before data is transmitted
- * number_of_enabled_led - Total number of LED to be enabled
- * data_mask - LEDs to set value
- * data - Corresponding value
- * mips0_access_mask - LEDs to set access right
- * mips0_access; - 1: the corresponding data is output from MIPS0, 0: MIPS1
- * f_data_clock_on_rising - 1: data clock on rising edge, 0: data clock on falling edge
- * Output:
- * int --- 0: Success
- * else: Error Code
- */
-int danube_led_config(struct led_config_param* param)
+int
+danube_led_config (struct led_config_param* param)
{
int ret;
- u32 reg_con0, reg_con1, reg_cpu0, reg_ar;
- u32 clean_reg_con0, clean_reg_con1, clean_reg_cpu0, clean_reg_ar;
- u32 f_setup_gpt2;
- u32 f_software_update;
- u32 new_led_on, new_adsl_on;
+ unsigned int reg_con0, reg_con1, reg_cpu0, reg_ar;
+ unsigned int clean_reg_con0, clean_reg_con1, clean_reg_cpu0, clean_reg_ar;
+ unsigned int f_setup_gpt2;
+ unsigned int f_software_update;
+ unsigned int new_led_on, new_adsl_on;
if ( !param )
return -EINVAL;
f_setup_gpt2 = 0;
- f_software_update = LED_CON0_SWU ? 0 : 1;
+ f_software_update = (readl(DANUBE_LED_CON0) & LED_CON0_SWU) ? 0 : 1;
new_led_on = f_led_on;
new_adsl_on = adsl_on;
ret = turn_on_led(new_adsl_on);
if ( ret )
{
-#if 1
printk("Setup GPIO error!\n");
-#endif
goto SETUP_GPIO_ERROR;
}
adsl_on = new_adsl_on;
f_led_on = 1;
}
-#if 0
- if ( (reg_con0 & 0x80000000) )
- printk("software update\n");
-#endif
-
/* Write Register */
if ( !f_led_on )
enable_led();
if ( !f_led_on )
disable_led();
-#if defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON
- *DANUBE_LED_CON0 &= 0x7FFFFFFF;
-#endif
-
-#if 0
- #if !defined(DEBUG_ON_AMAZON) || !DEBUG_ON_AMAZON
- printk("*0xBF10201C = 0x%08lX\n", *(unsigned long *)0xBF10201C);
- printk("*0xBE100B18 = 0x%08lX\n", *(unsigned long *)0xBE100B18);
- printk("*0xBE100B1C = 0x%08lX\n", *(unsigned long *)0xBE100B1C);
- printk("*0xBE100B20 = 0x%08lX\n", *(unsigned long *)0xBE100B20);
- printk("*0xBE100B24 = 0x%08lX\n", *(unsigned long *)0xBE100B24);
- #endif
- printk("*DANUBE_LED_CON0 = 0x%08X\n", *DANUBE_LED_CON0);
- printk("*DANUBE_LED_CON1 = 0x%08X\n", *DANUBE_LED_CON1);
- printk("*DANUBE_LED_CPU0 = 0x%08X\n", *DANUBE_LED_CPU0);
- printk("*DANUBE_LED_CPU1 = 0x%08X\n", *DANUBE_LED_CPU1);
- printk("*DANUBE_LED_AR = 0x%08X\n", *DANUBE_LED_AR);
-#endif
-
up(&led_sem);
return 0;
return -EINVAL;
}
+static int
+led_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int ret = -EINVAL;
+ struct led_config_param param;
-/*
- * ####################################
- * Init/Cleanup API
- * ####################################
- */
+ switch ( cmd )
+ {
+ case LED_CONFIG:
+ copy_from_user(¶m, (char*)arg, sizeof(param));
+ ret = danube_led_config(¶m);
+ break;
+ }
-/*
- * Description:
- * register device
- * Input:
- * none
- * Output:
- * 0 --- successful
- * else --- failure, usually it is negative value of error code
- */
-int __init danube_led_init(void)
+ return ret;
+}
+
+static int
+led_open (struct inode *inode, struct file *file)
{
- int ret;
+ return 0;
+}
+
+static int
+led_release (struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static struct file_operations led_fops = {
+ owner: THIS_MODULE,
+ ioctl: led_ioctl,
+ open: led_open,
+ release: led_release
+};
+
+static struct miscdevice led_miscdev = {
+ 151,
+ "led",
+ &led_fops,
+ NULL,
+ NULL,
+ NULL
+};
+
+int __init
+danube_led_init (void)
+{
+ int ret = 0;
struct led_config_param param = {0};
enable_led();
- /*
- * Set default value to registers to turn off all LED light.
- */
- *DANUBE_LED_AR = LED_AR_DEFAULT_VALUE;
- *DANUBE_LED_CPU0 = LED_LED_CPU0_DEFAULT_VALUE;
- *DANUBE_LED_CPU1 = LED_LED_CPU1_DEFAULT_VALUE;
- *DANUBE_LED_CON1 = LED_CON1_DEFAULT_VALUE;
- *DANUBE_LED_CON0 = LED_CON0_DEFAULT_VALUE;
-
-#if defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON
- *DANUBE_LED_CON0 &= 0x7FFFFFFF;
-#endif
+ writel(0, DANUBE_LED_AR);
+ writel(0, DANUBE_LED_CPU0);
+ writel(0, DANUBE_LED_CPU1);
+ writel(0, DANUBE_LED_CON1);
+ writel((0x80000000 | (DATA_CLOCKING_EDGE << 26)), DANUBE_LED_CON0);
disable_led();
sema_init(&led_sem, 0);
ret = misc_register(&led_miscdev);
- if ( ret == -EBUSY )
+ if (ret == -EBUSY)
{
led_miscdev.minor = MISC_DYNAMIC_MINOR;
ret = misc_register(&led_miscdev);
}
- if ( ret )
+
+ if (ret)
{
printk(KERN_ERR "led: can't misc_register\n");
- return ret;
- }
- else
+ goto out;
+ } else {
printk(KERN_INFO "led: misc_register on minor = %d\n", led_miscdev.minor);
+ }
module_id = THIS_MODULE ? (int)THIS_MODULE : ((MISC_MAJOR << 8) | led_miscdev.minor);
up(&led_sem);
-#if BOARD_TYPE == REFERENCE_BOARD
/* Add to enable hardware relay */
/* Map for LED on reference board
WLAN_READ LED11 OUT1 15
param.data_mask = 1 << 4;
param.data = 1 << 4;
danube_led_config(¶m);
-#endif
// by default, update by FSC clock (FPID)
param.operation_mask = CONFIG_OPERATION_UPDATE_CLOCK;
param.data = 1 << 5;
danube_led_config(¶m);
- return 0;
+out:
+ return ret;
}
-/*
- * Description:
- * deregister device
- * Input:
- * none
- * Output:
- * none
- */
-void __exit danube_led_exit(void)
+void __exit
+danube_led_exit (void)
{
int ret;