Esempio n. 1
0
void pmic_se1i_handler(void)
{

        TRACE_MSG0(REMOVE_TCD, "--");
        pmic_otg_wakeup();

#if 0
#if 1
        t_sensor_bits sense_bits;
        if (pmic_get_sensors(&sense_bits)) {
                printk(KERN_INFO "%s: pmic_get_sensors() failed\n",
                                __FUNCTION__);
                return;
        }
        TRACE_MSG1(REMOVE_TCD, "MC13783 EVENT: se1: %d", sense_bits.sense_se1s);
        otg_event(tcd_instance->otg,
                        (sense_bits.sense_se1s ? SE1_DET : SE1_DET_),
                        REMOVE_TCD, "MC13783 SE1");
#else
        otg_event(tcd_instance->otg,
                        (pmic_check_sense(sense_se1s) ? SE1_DET : SE1_DET_),
                        REMOVE_TCD, "MC13783 SE1");
#endif
#endif
}
Esempio n. 2
0
void pmic_idi_handler(void)
{

        TRACE_MSG0(REMOVE_TCD, "--");
        pmic_otg_wakeup();

#if 0
#if 1
        t_sensor_bits sense_bits;
        if (pmic_get_sensors(&sense_bits)) {
                printk(KERN_INFO "%s: pmic_get_sensors() failed\n",
                                __FUNCTION__);
                return;
        }

        TRACE_MSG2(REMOVE_TCD, "MC13783 EVENT: IDGNDS: %d IDFLOATS: %d",
                        sense_bits.sense_id_gnds, sense_bits.sense_id_floats);

        otg_event(tcd_instance->otg,
                        (sense_bits.sense_id_gnds ? ID_GND : ID_GND_) |
                        (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_),
                        REMOVE_TCD, "MC13783 IDI");
#else
        otg_event(tcd_instance->otg,
                        (pmic_check_sense(sense_id_gnds) ? ID_GND : ID_GND_) |
                        (pmic_check_sense(sense_id_floats) ? ID_FLOAT : ID_FLOAT_),
                        REMOVE_TCD, "MC13783 IDI");
#endif
#endif
}
Esempio n. 3
0
/*!
 * mxc_gptcr_timer_int_hndlr() - timer interrupt
 * @param irq
 * @param dev_id
 * @param regs
 */
irqreturn_t mxc_gptcr_timer_int_hndlr (int irq, void *dev_id, struct pt_regs *regs)
{               
        u32 gptsr = *_reg_GPT_GPTSR;


	*_reg_GPT_GPTIR &= ~(0x04);

        if (gptsr & (0x01 << 2)){
        	TRACE_MSG7(OCD, "cnt: %08x match: %08x gptsr: %08x GPTCNT: %08x GPTCR: %08x GPTSR: %08x GPTOCR3: %08x\n",
		                       mxc_gptcr_ticks_set, mxc_gptcr_match_set, gptsr,
		                        *_reg_GPT_GPTCNT, *_reg_GPT_GPTCR, *_reg_GPT_GPTSR, *_reg_GPT_GPTOCR3);

		*_reg_GPT_GPTCR &= ~(0x7 << 26);
		*_reg_GPT_GPTOCR3 = 0;
                TRACE_MSG0(OCD, "OCM3");
                TRACE_MSG1(OCD, "active: %x", mxc_gptcr_active);
                if (mxc_gptcr_active) {
                        TRACE_MSG0(OCD, "calling otg_event"); 
                        mxc_gptcr_active = 0;
                        otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT");
                }
                else {
                        TRACE_MSG0(OCD, "skipping otg_event"); 
                }
		*_reg_GPT_GPTSR |= 0x4;
		return IRQ_HANDLED;
	}

	if (!mxc_shared_int)
		*_reg_GPT_GPTIR |= 0x4;
		
	return IRQ_NONE;
}
Esempio n. 4
0
/*!
 * l26_ocd_init() - used to initialize/enable or disable the tcd driver
 * @param otg
 * @param flag
 */
static void l26_ocd_init(struct otg_instance *otg, u8 flag)
{
        struct ocd_instance *ocd = otg->ocd;

        TRACE_MSG0(ocd->TAG, "--");
        switch (flag) {
        case SET:
                TRACE_MSG0(ocd->TAG, "FS_OCD_EN SET");
                //l26_init();
                otg_event(otg, TCD_OK | ID_FLOAT, otg->ocd->TAG, "OCD_OK");
                break;
        case RESET:
                //l26_exit();
                TRACE_MSG0(ocd->TAG, "FS_OCD_EN RESET");
                otg_event(otg, TCD_OK | ID_FLOAT, otg->ocd->TAG, "OCD_OK");
                break;
        }
}
Esempio n. 5
0
/*! pmic_otg_event_bh - pmic otg event handler
 * @param data - otg instance
 */
void pmic_otg_event_bh(void *data)
{
        struct otg_instance *otg = (struct otg_instance *) data;
        otg_current_t inputs;
        t_sensor_bits sense_bits;
        static BOOL force = TRUE;
        static otg_current_t inputs_saved = 0;

        if (pmic_get_sensors(&sense_bits)) {
                printk(KERN_INFO "%s: pmic_get_sensors() failed\n",
                                __FUNCTION__);
                return;
        }
        TRACE_MSG6(REMOVE_TCD,
                        "usb4v4s%c usb2v0s%c usb0v8s:%c id_gnds%c id_floats%c id_se1s%c",
                        sense_bits.sense_usb4v4s ? ' ' : '/',
                        sense_bits.sense_usb2v0s ? ' ' : '/',
                        sense_bits.sense_usb0v8s ? ' ' : '/',
                        sense_bits.sense_id_gnds ? ' ' : '/',
                        sense_bits.sense_id_floats ? ' ' : '/',
                        sense_bits.sense_se1s ? ' ' : '/');

        inputs = (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) |
                (sense_bits.
                 sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ |
                         A_SESS_VLD_)) |
                (sense_bits.sense_usb0v8s ? B_SESS_END_ : B_SESS_END) | (sense_bits.
                                sense_id_gnds
                                ? ID_GND :
                                ID_GND_) |
                (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_) | (sense_bits.
                                sense_se1s ?
                                SE1_DET :
                                SE1_DET_) |
                (det_dp_hi ? DP_HIGH : DP_HIGH_) | (det_dm_hi ? DM_HIGH : DM_HIGH_);

        //      printk(KERN_INFO" inputs: %8X\n", inputs);
        TRACE_MSG4(REMOVE_TCD,
                        "MC13783 EVENT: sense_bits: %8x otg inputs: %8x saved: %x diff: %x",
                        sense_bits.sense_se1s, inputs, inputs_saved,
                        inputs ^ inputs_saved);

        RETURN_UNLESS(force || (inputs ^ inputs_saved));

        inputs_saved = inputs;
        otg_event(REMOVE_tcd_instance->otg, inputs, REMOVE_TCD, "PMIC OTG EVENT");

        //      gpio_config_int_en(2, 17, TRUE);
        //      gpio_config_int_en(2, 16, TRUE);

        //      gpio_clear_int (2, 17);
        //      gpio_clear_int (2, 16);

}
Esempio n. 6
0
/*!
 * mxc_ocd_init() - used to initialize/enable or disable the tcd driver
 * @param otg
 * @param flag
 */
void mxc_ocd_init(struct otg_instance *otg, u8 flag)
{
        TRACE_MSG0(otg->ocd->TAG, "--");
        switch (flag) {
        case SET:
                TRACE_MSG0(otg->ocd->TAG, "FS_otg->ocd->TAG_EN SET");
                mxc_init(otg);
                break;
        case RESET:
                mxc_exit(otg);
                TRACE_MSG0(otg->ocd->TAG, "FS_otg->ocd->TAG_EN RESET");
                break;
        }
        otg_event(otg, OCD_OK, otg->ocd->TAG, "MX21 OK");
}
Esempio n. 7
0
/*!
 * mxc_pmic_usbi_handler() - event handler
 *
 *
 *
 */
void pmic_usbi_handler(void)
{

        TRACE_MSG0(REMOVE_TCD, "--");
        pmic_otg_wakeup();

#if 0
#if 1
        t_sensor_bits sense_bits;
        if (pmic_get_sensors(&sense_bits)) {
                printk(KERN_INFO "%s: pmic_get_sensors() failed\n",
                                __FUNCTION__);
                return;
        }

        TRACE_MSG3(REMOVE_TCD, "MC13783 EVENT: 4V4S: %d 2V0S: %d 0V8S: %d",
                        sense_bits.sense_usb4v4s,
                        sense_bits.sense_usb2v0s, sense_bits.sense_usb0v8s);

        otg_event(tcd_instance->otg,
                        (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) |
                        (sense_bits.
                         sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ |
                                 A_SESS_VLD_)) |
                        (sense_bits.sense_usb0v8s ? B_SESS_END : B_SESS_END_), REMOVE_TCD,
                        "MC13783 USBI");
#else
        otg_event(tcd_instance->otg,
                        (pmic_check_sense(sense_usb4v4s) ? VBUS_VLD : VBUS_VLD_) |
                        (pmic_check_sense(sense_usb4v4s)
                         ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) |
                        (pmic_check_sense(sense_usb0v8s) ? B_SESS_END :
                         B_SESS_END_), REMOVE_TCD, "MC13783 USBI");
#endif
#endif
}
Esempio n. 8
0
/*! mxc_pmic_tcd_init() - used to enable mc13783
 * @param otg - otg instance pointer
 * @param flag -
 *
 */
void mxc_pmic_tcd_init(struct otg_instance *otg, u8 flag)
{
        struct tcd_instance *tcd = otg->tcd;
        switch (flag) {
        case SET:
        case PULSE:
                TRACE_MSG0(tcd->TAG, "SET/PULSE");
                break;
        case RESET:
                TRACE_MSG0(tcd->TAG, "RESET");
                break;
        }
        pmic_otg_wakeup();
        otg_event (otg, OCD_OK, otg->tcd->TAG, "MC13783 OK");
}
Esempio n. 9
0
void mxc_hrt_callback (unsigned long arg)
{

        TRACE_MSG1(OCD, "checking active: %d", mxc_hr_active);
        RETURN_UNLESS(mxc_hr_active);
        mxc_hr_active = FALSE;
        TRACE_MSG1(OCD, "resetting active: %d", mxc_hr_active);

	if (mxc_hr_usec_set >= 1000000) {	//if requested period is in the range of 1 sec
	       	hr_timer.expires = jiffies + ((mxc_hr_usec_set/1000000)*mxc_hr_jiffy_per_sec);
		hr_timer.arch_cycle_expires = get_arch_cycles(jiffies);
	        hr_timer.function = mxc_hrt_callback;
	}
	else {
        	hr_timer.expires = jiffies;
	        hr_timer.arch_cycle_expires = get_arch_cycles(jiffies);
        	if (mxc_hr_usec_set < 100) {
	                TRACE_MSG1(OCD, "usec: %d set to minimum 100", mxc_hr_usec_set);
                	mxc_hr_usec_set = 100;
        	}
	        hr_timer.arch_cycle_expires += nsec_to_arch_cycle(mxc_hr_usec_set * 1000);
	        //hr_timer.arch_cycle_expires += nsec_to_arch_cycle(100 * 1000 * 1000);
        	while (hr_timer.arch_cycle_expires >= arch_cycles_per_jiffy)
	        {
        	        hr_timer.expires++;
                	hr_timer.arch_cycle_expires -= arch_cycles_per_jiffy;
	        }
	}	//end of else	

	TRACE_MSG3 (OCD, "usec: %d expires: %8u arch_cycle_expires: %8u", 
                        mxc_hr_usec_set, hr_timer.expires, hr_timer.arch_cycle_expires);
	otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT");


//        add_timer(&hr_timer);
}
Esempio n. 10
0
void mc13783_otg_event_bh (void *arg)
{
        u64 inputs;
        t_sense_bits sense_bits;
        static BOOL force = TRUE;
        static u64 inputs_saved = 0;

// Note: power_ic has USB4V4S labelled as USBI, which is incorrect

	// Get the sense bits, return if any fail to be read. 
	if ( (sense_bits.sense_usb4v4s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USBI)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() usb4v4s failed\n", __FUNCTION__);
		return;
        }       
	if ( (sense_bits.sense_usb2v0s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USB2V0S)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() usb2v0s failed\n", __FUNCTION__);
		return;
        }       
	if ( (sense_bits.sense_usb0v8s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USB0V8S)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() usb0v8s failed\n", __FUNCTION__);
		return;
        }       
	if ( (sense_bits.sense_id_floats = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_ID_FLOAT)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() id_floats failed\n", __FUNCTION__);
		return;
        }       
	if ( (sense_bits.sense_id_gnds = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_ID_GROUND)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() id_gnds failed\n", __FUNCTION__);
		return;
        }       
	if ( (sense_bits.sense_se1s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_SE1I)) < 0) {
                printk(KERN_INFO"%s: mc13783_get_sense() se1s failed\n", __FUNCTION__);
		return;
        }       

    // Factory cable check meant for USB B device only. If IDGNDS is True 
    // adjust the value of IDGNDS to be False, so the state machine thinks it's a
    // traditional device and not a Dual role device.
#ifdef CONFIG_OTG_USB_PERIPHERAL
    if ( sense_bits.sense_id_gnds ) {
        sense_bits.sense_id_gnds = FALSE;
	    TRACE_MSG0(TCD, "Factory Cable detected and IDGND modified to false"); 
	    // printk("Factory Cable detected and IDGND modified to false\n"); 
    }
#endif

	inputs = (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) |
		 (sense_bits.sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) |
		 (sense_bits.sense_usb0v8s ? B_SESS_END_ : B_SESS_END) |
		 (sense_bits.sense_id_gnds ? ID_GND : ID_GND_) |
                 (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_) |
		 (sense_bits.sense_se1s ? SE1_DET : SE1_DET_) |
		 (det_dp_hi ? DP_HIGH : DP_HIGH_) |
		 (det_dm_hi ? DM_HIGH : DM_HIGH_);



	TRACE_MSG4(TCD, "MC13783 EVENT: sense_bits: %8x otg inputs: %8x saved: %x diff: %x", 
                        sense_bits.sense_se1s, inputs, inputs_saved, inputs ^ inputs_saved);

        RETURN_UNLESS(force || (inputs ^ inputs_saved));

        inputs_saved = inputs;
        otg_event(tcd_instance->otg, inputs, TCD, "MC13783 OTG EVENT");
}
Esempio n. 11
0
/*!
 * l26_ocd_start_timer() - start a timer for otg state machine
 * Set or reset timer to interrupt in number of uS (micro-seconds). 
 *
 * @param otg
 * @param usec
 */
int l26_ocd_start_timer(struct otg_instance *otg, int usec)
{
	otg_event(otg, TMOUT, otg->ocd->TAG, "l26 Timer");
        return 0;
}
Esempio n. 12
0
/*! 
 * otg_message_ioctl_internal() - ioctl call
 * @param cmd ioctl command.
 * @param arg ioctl arguement.
 * @return non-zero for error.
 */
int otg_message_ioctl_internal(unsigned int cmd, unsigned long arg)
{
        int i;
        int len;
        int flag;
        struct otg_admin_command admin_command;
        struct otg_status_update status_update;
        struct otg_firmware_info firmware_info;
        struct otg_state otg_state;
        struct otg_test otg_test;
        struct otg_ioctl_name *otg_ioctl_name;
        static char func_buf[32];
        char *sp, *dp;
	char *name;

        //printk(KERN_INFO"%s: cmd: %08x %08x\n", __FUNCTION__, cmd, _IOC_NR(cmd)); 

        //TRACE_MSG2(CORE, "cmd: %08x %08x", cmd, _IOC_NR(cmd)); 

        switch (_IOC_DIR(cmd)) {
        case _IOC_NONE:
                switch (_IOC_NR(cmd)) {
                }
                break;

        case _IOC_WRITE:
                switch (_IOC_NR(cmd)) {
                case _IOC_NR(OTGADMIN_SET_FUNCTION):
                        TRACE_MSG0(CORE, "OTGADMIN_SET_FUNCTION");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        memset(&admin_command, 0x41, sizeof(struct otg_admin_command));
                        RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd)));
                        len = sizeof(mesg_otg_instance->function_name);
                        admin_command.string[len] = '\0';
                        //TRACE_MSG1(CORE, "Setting function: \"%s\"", mesg_otg_instance->function_name);
                        strncpy(mesg_otg_instance->function_name, admin_command.string, len);
                        mesg_otg_instance->function_name[len-1] = '\0';
                        return 0;

                case _IOC_NR(OTGADMIN_SET_SERIAL):
                        TRACE_MSG0(CORE, "OTGADMIN_SET_SERIAL");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd)));
                        admin_command.string[sizeof(admin_command.string) - 1] = '\0';
                        //printk(KERN_INFO"%s: string: %s\n", __FUNCTION__, admin_command.string);
                        for (sp = admin_command.string, dp = mesg_otg_instance->serial_number, i = 0; 
                                        *sp && (i < (sizeof(admin_command.string) - 1)); i++, sp++)
                                if (isxdigit(*sp)) *dp++ = toupper(*sp);

                        *sp = '\0';
                        //TRACE_MSG1(CORE, "serial_number: %s", mesg_otg_instance->serial_number);
                        printk(KERN_INFO"%s: serial: %s\n", __FUNCTION__, mesg_otg_instance->serial_number);
                        return 0;

                case _IOC_NR(OTGADMIN_SET_INFO):
                        TRACE_MSG0(CORE, "OTGADMIN_SET_INFO");
                        memset(&firmware_info, 0x41, sizeof(firmware_info));
                        RETURN_EINVAL_IF(copy_from_user(&firmware_info, (void *)arg, _IOC_SIZE(cmd)));


                        return otg_mesg_set_firmware_info(&firmware_info);
                        return 0;

                case _IOC_NR(OTGADMIN_SET_STATE):
                        //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE");
                        RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd)));

                        RETURN_EINVAL_UNLESS(otg_firmware_loading);
                        //TRACE_MSG0(CORE, "OTGADMIN_SET_STATE");
                        RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loading->number_of_states);
                        memcpy(otg_firmware_loading->otg_states + otg_state.state, &otg_state, sizeof(otg_state));
                        return 0;

                case _IOC_NR(OTGADMIN_SET_TEST):
                        //TRACE_MSG0(CORE, "OTGADMIN_GET/SET");
                        RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd)));

                        RETURN_EINVAL_UNLESS(otg_firmware_loading);
                        //TRACE_MSG1(CORE, "OTGADMIN_SET_TEST : %d", otg_test.test);
                        RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loading->number_of_tests);
                        memcpy(otg_firmware_loading->otg_tests + otg_test.test, &otg_test, sizeof(otg_test));
                        return 0;
                }
                break;

        case _IOC_READ:
                switch (_IOC_NR(cmd)) {
                case _IOC_NR(OTGADMIN_GET_FUNCTION):
                        TRACE_MSG0(CORE, "OTGADMIN_GET_FUNCTION");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd)));
                        name = otg_usbd_ops->function_name(admin_command.n);
                        admin_command.string[0] = '\0';
                        if (name)
                                strncat(admin_command.string, name, sizeof(admin_command.string));

                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd)));
                        return 0;

                case _IOC_NR(OTGADMIN_GET_SERIAL):
                        TRACE_MSG0(CORE, "OTGADMIN_GET_SERIAL");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        strncpy(admin_command.string, mesg_otg_instance->serial_number, sizeof(admin_command.string));
                        admin_command.string[sizeof(admin_command.string) - 1] = '\0';
                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd)));
                        return 0;

                case _IOC_NR(OTGADMIN_STATUS):
                        //TRACE_MSG0(CORE, "OTGADMIN_STATUS");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        memset(&status_update, 0, sizeof(struct otg_status_update));

                        otg_mesg_get_status_update(&status_update);

                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &status_update, _IOC_SIZE(cmd)));
                        return 0;

                case _IOC_NR(OTGADMIN_GET_INFO):
                        TRACE_MSG0(CORE, "OTGADMIN_GET_INFO");
                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);

                        otg_mesg_get_firmware_info(&firmware_info);

                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &firmware_info, _IOC_SIZE(cmd)));
                        //TRACE_MSG0(CORE, "OTGADMIN_GET_INFO: finished");
                        return 0;

                case _IOC_NR(OTGADMIN_GET_STATE):
                        //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE");
                        RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd)));

                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        //TRACE_MSG0(CORE, "OTGADMIN_GET_STATE");
                        RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loaded->number_of_states);
                        memcpy(&otg_state, otg_firmware_loaded->otg_states + otg_state.state, sizeof(otg_state));
                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_state, _IOC_SIZE(cmd)));
                        return 0;

                case _IOC_NR(OTGADMIN_GET_TEST):
                        //TRACE_MSG0(CORE, "OTGADMIN_GET/SET");
                        RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd)));

                        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
                        //TRACE_MSG1(CORE, "OTGADMIN_GET_TEST: %d", otg_test.test);
                        RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loaded->number_of_tests);
                        memcpy(&otg_test, otg_firmware_loaded->otg_tests + otg_test.test, sizeof(otg_test));
                        RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_test, _IOC_SIZE(cmd)));
                        return 0;
                }
                break;
        }

        TRACE_MSG0(CORE, "OTGADMIN_");
        RETURN_EINVAL_UNLESS(otg_firmware_loaded);
        for (otg_ioctl_name = otg_ioctl_names; otg_ioctl_name && otg_ioctl_name->cmd; otg_ioctl_name++) {
                //TRACE_MSG4(CORE, "lookup: %04x %04x %08x %08x", 
                //                _IOC_NR(cmd), _IOC_NR(otg_ioctl_name->cmd), cmd, otg_ioctl_name->cmd);
                BREAK_IF(_IOC_NR(otg_ioctl_name->cmd) == _IOC_NR(cmd));
        }
        //TRACE_MSG3(CORE, "checking %d %08x %08x", _IOC_NR(cmd), otg_ioctl_name->cmd, cmd);
        RETURN_EINVAL_UNLESS(otg_ioctl_name->cmd);
        __get_user(flag, (int *)arg);
        //TRACE_MSG3(CORE, "%s %08x flag: %d", otg_ioctl_name->name, otg_ioctl_name->set, flag);
        otg_event (mesg_otg_instance, flag ? otg_ioctl_name->set : _NOT(otg_ioctl_name->set), CORE, otg_ioctl_name->name);
        return 0;
}