/*!
 * @brief Used to configure the device for debouncing.
 *
 * When the Connecting State: debounce  is entered, it indicates
 * that one of the other states believes that an accessory may be attached to the
 * phone.  It is the job of the Connecting: Debounce state to determine if an
 * accessory is attached and then to identify the accessory.  Some accessories may
 * be able to be identified in this state (i.e., no additional steps are needed in
 * order to uniquely identify the accessory) where other accessories require
 * additional processing before they can be identified.  This additional processing
 * is handled in the other states in the Connecting family.
 *
 * The entry function is responsible for configuring the hardware in the way that
 * will allow for the debouncing of accessory insertion and to begin the process
 * of accessory identification.  Additionally, a number of debounce variables will
 * need to be reset. 
 *
 * @param prev_state the previous EMU state
 * @param polling_interval a return parameter that holds the "polling rate"
 */
void debounce_dev_type_enter(EMU_STATE_T prev_state, int *polling_interval)
{
    /* Mask ID and VBUS interrupts */
    power_ic_event_mask(EMU_INT_VBUS);
    power_ic_event_mask(EMU_INT_ID);
    
    *polling_interval = EMU_POLL_CONTINUE;
    
    emu_default_register_settings(polling_interval);
}
/*!
 * @brief Used to mask the EMU bus interrupts and always transitions directly
 *        to the Connecting State: debounce.
 *
 * The handler will be called if an ID, VBUS or SE1 interrupt occur, or if the
 * unpowered SIHF delay expires. If one of the interrupts is seen or the unpowered
 * SIHF delay expires, the state will be change to the Connecting State: debounce
 * in order to complete the identification of the accessory.
 *
 * @param polling_interval a return parameter that holds the "polling rate"
 *
 * @return next_state tells the state machine what the next EMU state is
 */
EMU_STATE_T unpowered_sihf_handler(int *polling_interval)
{
    /* Mask the interrupts */
    power_ic_event_mask(EMU_INT_SE1);
    power_ic_event_mask(EMU_INT_VBUS);
    power_ic_event_mask(EMU_INT_ID);

    *polling_interval = EMU_POLL_CONTINUE;

    /* Always go back to debouncing */
    return EMU_STATE_CONNECTING__DEBOUNCE_DEV_TYPE;
}
static int emu_proc_open(struct inode *inode, struct file *file)
{
    /* take mutex */
    if(down_interruptible(&emu_proc_opened_mutex))
    {
        tracemsg(_k_d("process received signal while waiting for power ic opened mutex. Exiting."));
        return -EINTR;
    }

    /* Check if the proc is not already open */
    if (emu_proc_opened == true)
    {
        tracemsg(_k_d("/proc/emu control already opened.\n"));

         /* Release mutex */
        up(&emu_proc_opened_mutex);
        return -EBUSY;
    }
    /* Set the opened state */
    emu_proc_opened = true;

    /* MASK VBUS INT */
    power_ic_event_mask(EMU_INT_VBUS);

    /* Unsubsribe usb detection light driver handler on VBUS */
    power_ic_event_unsubscribe(EMU_INT_VBUS,usb_detection_int_handler);

    /* Subscribe to the EMU interrupt events */
    power_ic_event_subscribe(EMU_INT_VBUS, emu_glue_int_handler);
    power_ic_event_subscribe(EMU_INT_ID, emu_glue_int_handler);
    power_ic_event_subscribe(EMU_INT_SE1, emu_glue_int_handler);
    
    /* Release mutex */
    up(&emu_proc_opened_mutex);
    
    return 0;
}