-int
-danube_led_config (struct led_config_param* param)
-{
- int ret;
- 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;
-
- down(&led_sem);
-
- reg_con0 = *DANUBE_LED_CON0;
- reg_con1 = *DANUBE_LED_CON1;
- reg_cpu0 = *DANUBE_LED_CPU0;
- reg_ar = *DANUBE_LED_AR;
-
- clean_reg_con0 = 1;
- clean_reg_con1 = 1;
- clean_reg_cpu0 = 1;
- clean_reg_ar = 1;
-
- f_setup_gpt2 = 0;
-
- f_software_update = (readl(DANUBE_LED_CON0) & LED_CON0_SWU) ? 0 : 1;
-
- new_led_on = f_led_on;
- new_adsl_on = adsl_on;
-
- /* ADSL or LED */
- if ( (param->operation_mask & CONFIG_OPERATION_UPDATE_SOURCE) )
- {
- if ( param->led > 0x03 || param->source > 0x03 )
- goto INVALID_PARAM;
- clean_reg_con0 = 0;
- reg_con0 = set_update_source(reg_con0, param->led, param->source);
-#if 0 // ADSL0,1 is source for bit 0, 1 in shift register
- new_adsl_on = param->source;
-#endif
- }
-
- /* Blink */
- if ( (param->operation_mask & CONFIG_OPERATION_BLINK) )
- {
- if ( (param->blink_mask & 0xFF000000) || (param->blink & 0xFF000000) )
- goto INVALID_PARAM;
- clean_reg_con0 = 0;
- reg_con0 = set_blink_in_batch(reg_con0, param->blink_mask, param->blink);
- }
-
- /* Edge */
- if ( (param->operation_mask & CONFIG_DATA_CLOCK_EDGE) )
- {
- clean_reg_con0 = 0;
- reg_con0 = set_data_clock_edge(reg_con0, param->f_data_clock_on_rising);
- }
-
- /* Update Clock */
- if ( (param->operation_mask & CONFIG_OPERATION_UPDATE_CLOCK) )
- {
- if ( param->update_clock > 0x02 || (param->update_clock == 0x02 && param->fpid > 0x3) )
- goto INVALID_PARAM;
- clean_reg_con1 = 0;
- f_software_update = param->update_clock == 0 ? 1 : 0;
- if ( param->update_clock == 0x01 )
- f_setup_gpt2 = 1;
- reg_con1 = set_update_clock(reg_con1, param->update_clock, param->fpid);
- }
-
- /* Store Mode */
- if ( (param->operation_mask & CONFIG_OPERATION_STORE_MODE) )
- {
- clean_reg_con1 = 0;
- reg_con1 = set_store_mode(reg_con1, param->store_mode);
- }
-
- /* Shift Clock */
- if ( (param->operation_mask & CONFIG_OPERATION_SHIFT_CLOCK) )
- {
- if ( param->fpis > 0x03 )
- goto INVALID_PARAM;
- clean_reg_con1 = 0;
- reg_con1 = set_shift_clock(reg_con1, param->fpis);
- }
-
- /* Data Offset */
- if ( (param->operation_mask & CONFIG_OPERATION_DATA_OFFSET) )
- {
- if ( param->data_offset > 0x03 )
- goto INVALID_PARAM;
- clean_reg_con1 = 0;
- reg_con1 = set_data_offset(reg_con1, param->data_offset);
- }
-
- /* Number of LED */
- if ( (param->operation_mask & CONFIG_OPERATION_NUMBER_OF_LED) )
- {
- if ( param->number_of_enabled_led > 0x24 )
- goto INVALID_PARAM;
-
- /*
- * If there is at lease one LED enabled, the GPIO pin must be setup.
- */
- new_led_on = param->number_of_enabled_led ? 1 : 0;
-
- clean_reg_con1 = 0;
- reg_con1 = set_number_of_enabled_led(reg_con1, param->number_of_enabled_led);
- }
-
- /* LED Data */
- if ( (param->operation_mask & CONFIG_OPERATION_DATA) )
- {
- if ( (param->data_mask & 0xFF000000) || (param->data & 0xFF000000) )
- goto INVALID_PARAM;
- clean_reg_cpu0 = 0;
- reg_cpu0 = set_data_in_batch(reg_cpu0, param->data_mask, param->data);
- if ( f_software_update )
- {
- clean_reg_con0 = 0;
- reg_con0 |= 0x80000000;
- }
- }
-
- /* Access Right */
- if ( (param->operation_mask & CONFIG_OPERATION_MIPS0_ACCESS) )
- {
- if ( (param->mips0_access_mask & 0xFF000000) || (param->mips0_access & 0xFF000000) )
- goto INVALID_PARAM;
- clean_reg_ar = 0;
- reg_ar = set_access_right(reg_ar, param->mips0_access_mask, param->mips0_access);
- }
-
- /* Setup GPT */
- if ( f_setup_gpt2 && !new_adsl_on ) // If ADSL led is on, GPT is disabled.
- {
- ret = 0;
-
- if ( gpt_on )
- {
- if ( gpt_freq != param->fpid )
- {
- release_gpt(2);
- gpt_on = 0;
- ret = setup_gpt(2, param->fpid);
- }
- }
- else
- ret = setup_gpt(2, param->fpid);
-
- if ( ret )
- {
-#if 1
- printk("Setup GPT error!\n");
-#endif
- goto SETUP_GPT_ERROR;
- }
- else
- {
-#if 0
- printk("Setup GPT successfully!\n");
-#endif
- gpt_on = 1;
- }
- }
- else
- if ( gpt_on )
- {
- release_gpt(2);
- gpt_on = 0;
- }
-
- /* Turn on LED */
- if ( new_adsl_on )
- new_led_on = 1;
- if ( !new_led_on || adsl_on != new_adsl_on )
- {
- turn_off_led(adsl_on);
- f_led_on = 0;
- adsl_on = 0;
- }
- if ( !f_led_on && new_led_on )
- {
- ret = turn_on_led(new_adsl_on);
- if ( ret )
- {
- printk("Setup GPIO error!\n");
- goto SETUP_GPIO_ERROR;
- }
- adsl_on = new_adsl_on;
- f_led_on = 1;
- }
-
- /* Write Register */
- if ( !f_led_on )
- enable_led();
- if ( !clean_reg_ar )
- *DANUBE_LED_AR = reg_ar;
- if ( !clean_reg_cpu0 )
- *DANUBE_LED_CPU0 = reg_cpu0;
- if ( !clean_reg_con1 )
- *DANUBE_LED_CON1 = reg_con1;
- if ( !clean_reg_con0 )
- *DANUBE_LED_CON0 = reg_con0;
- if ( !f_led_on )
- disable_led();
-
- up(&led_sem);
- return 0;
-
-SETUP_GPIO_ERROR:
- release_gpt(2);
- gpt_on = 0;
-SETUP_GPT_ERROR:
- up(&led_sem);
- return ret;
-
-INVALID_PARAM:
- up(&led_sem);
- 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;
-
- 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;
-}