コード例 #1
0
/*!
 * @brief Validates that the PPD is a supported device
 *
 * The event handler for this state will be called after a delay to ensure that
 * the output of the USB transceiver has stabilized.  If the D+ line is low, the
 * accessory is a valid phone-powered accessory, so the state is changed to the
 * Connecting State: PPD validate state to identify the accessory.  If the D+ line
 * is high, the accessory is invalid, so the state is changed to the Connected
 * State indicating the invalid accessory.  As a separate verification step, the
 * event handler will also verify that the accessory still appears to be a
 * phone-powered accessory (as opposed to a self-powered accessory).  If the
 * accessory does not appear to be a phone-powered accessory, the state is reset
 * to the Connecting: debounce_dev_type state to attempt to re-debounce the
 * insertion 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 ppd_validate_handler(int *polling_interval)
{
    if (get_device_type() != EMU_DEV_TYPE_PPD)
    {
        tracemsg(_k_d("EMU: ppd_validate_handler: device_type changed! next_state = EMU_STATE_CONNECTING__DEBOUNCE_DEV_TYPE"));
        
        /* Something changed, debounce the device type again */
        *polling_interval = EMU_POLL_CONTINUE;
        
        return EMU_STATE_CONNECTING__DEBOUNCE_DEV_TYPE;
    }

    if (!get_bus_state(EMU_BUS_SIGNAL_DPLUS))
    {
        tracemsg(_k_d("EMU: ppd_validate_handler: D+ is low, next_state = EMU_STATE_CONNECTING__PPD_IDENTIFY"));
        
        /* If D+ is low and the device type has not changed
           go on to the next layer of PPD detection */
        *polling_interval = EMU_POLL_CONTINUE;
        
        return EMU_STATE_CONNECTING__PRE_PPD_IDENTIFY;
    }

    tracemsg(_k_d("EMU: ppd_validate_handler : D+ is high, current_device = MOTO_ACCY_TYPE_INVALID, next_state = EMU_STATE_CONNECTED__INVALID"));
    
    /* D+ is not low at this point so the device is invalid */
    emu_current_device = MOTO_ACCY_TYPE_INVALID;

    *polling_interval = EMU_POLL_CONTINUE;
    
    return EMU_STATE_CONNECTED__INVALID;
}
コード例 #2
0
ファイル: charger.c プロジェクト: muromec/linux-ezxdev
/*!
 * @brief ioctl() handler for the charger control interface.
 *
 * This function is the ioctl() interface handler for all charger control operations. It is 
 * not called directly through an ioctl() call on the power IC device, but is executed 
 * from the core ioctl handler for all ioctl requests in the range for charger operations.
 *
 * @param        cmd       ioctl() request received.
 * @param        arg       additional information about request, specific to each request.
 *
 * @return 0 if successful.
 */
int charger_ioctl(unsigned int cmd, unsigned long arg)
{
    int error;
    int temp;     
    tracemsg(_k_d("Charger control ioctl(), request 0x%X (cmd 0x%X)"),(int) cmd, _IOC_NR(cmd));
    
    /* Handle the request. Note that no charger control operations require a structure to be
     * passed - all operations take a single parameter passed by value. */
    switch(cmd)
    {
        case POWER_IC_IOCTL_CHARGER_SET_CHARGE_VOLTAGE:
            return(power_ic_charger_set_charge_voltage((int)arg));
            break;
            

        case POWER_IC_IOCTL_CHARGER_SET_CHARGE_CURRENT:
            return(power_ic_charger_set_charge_current((int)arg));
            break;
            

        case POWER_IC_IOCTL_CHARGER_SET_TRICKLE_CURRENT:
            return(power_ic_charger_set_trickle_current((int)arg));
            break;
            

        case POWER_IC_IOCTL_CHARGER_SET_POWER_PATH:
            return(power_ic_charger_set_power_path((int)arg));
            break;

        case POWER_IC_IOCTL_CHARGER_GET_OVERVOLTAGE:
            /* Read the state of overvoltage from the hardware. */
            if((error = power_ic_charger_get_overvoltage(&temp)))
            {
                return error;
            }
            
            /* Return the read state back to the caller. */
            if(put_user(temp, (int *)arg))
            {
                return -EFAULT;
            }
            break;
            
        case POWER_IC_IOCTL_CHARGER_RESET_OVERVOLTAGE:
            return(power_ic_charger_reset_overvoltage());
            break;

        default: /* This shouldn't be able to happen, but just in case... */
            tracemsg(_k_d("=> 0x%X unsupported charger ioctl command"), (int) cmd);
            return -ENOTTY;
            break;
    
    }
    return 0;
}
コード例 #3
0
ファイル: ring.c プロジェクト: gamma62/eda
/* internal function for bookmark set, known limitation: one line -- one bookmark
*/
void
set_bookmark (int bm_i)
{
	char *bn=NULL;
	char *sample=NULL;
	int slen=0, blen=0;

	if ((bm_i > 0 && bm_i < 10) && (TEXT_LINE(CURR_LINE))) {

		/* check line's bookmark bits clean
		 * (known limitation: one line -- one bookmark)
		 */
		if (CURR_LINE->lflag & LSTAT_BM_BITS) {
			tracemsg("this line has already bookmark %d set",
				(CURR_LINE->lflag & LSTAT_BM_BITS) >> BM_BIT_SHIFT);
			return;
		}

		/* allowed to overwrite other setting of the same bm_i (clear and set)
		*/
		clr_bookmark (bm_i);

		cnf.bookmark[bm_i].ring = cnf.ring_curr;
		cnf.bookmark[bm_i].sample[0] = '\0';
		CURR_LINE->lflag |= (bm_i << BM_BIT_SHIFT) & LSTAT_BM_BITS;

		/* prepare sample of [block-name: ]sample-string-from-the-line
		*/
		bn = block_name(cnf.ring_curr);
		if (bn != NULL && bn[0] != '\0') {
			blen = strlen(bn);
			if (csere (&sample, &slen, 0, slen, bn, blen) || csere (&sample, &slen, slen, 0, ": ", 2)) {
				FREE(sample); sample = NULL;
			}
		}
		FREE(bn); bn = NULL;

		if (sample && !csere (&sample, &slen, slen, 0, CURR_LINE->buff, CURR_LINE->llen)) {
			if (slen>0 && sample[slen-1]=='\n') {
				sample[--slen] = '\0';	/* remove trailing newline */
			}
			strip_blanks (STRIP_BLANKS_FROM_END|STRIP_BLANKS_FROM_BEGIN|STRIP_BLANKS_SQUEEZE, sample, &slen);
			strncpy(cnf.bookmark[bm_i].sample, sample, sizeof(cnf.bookmark[bm_i].sample));
			cnf.bookmark[bm_i].sample[sizeof(cnf.bookmark[bm_i].sample)-1] = '\0';

			tracemsg("bookmark %d set", bm_i);
		} else {
			tracemsg("bookmark set failed");
		}
		FREE(sample); sample = NULL;

	}
コード例 #4
0
ファイル: peripheral.c プロジェクト: muromec/linux-ezxdev
/*!
 * This function is the ioctl() interface handler for all peripheral operations. It is not called
 * directly through an ioctl() call on the power IC device, but is executed from the core ioctl
 * handler for all ioctl requests in the range for peripherals.
 *
 * @param        cmd         the ioctl() command
 * @param        arg         the ioctl() argument
 *
 * @return       This function returns 0 if successful.
 */
int periph_ioctl(unsigned int cmd, unsigned long arg)
{
    int retval = 0;
    int data = (int) arg;
    
    /* Get the actual command from the ioctl request. */
    unsigned int cmd_num = _IOC_NR(cmd);

    tracemsg(_k_d("peripheral ioctl(), request 0x%X (cmd %d)"),(int) cmd, (int)cmd_num);
    
    /* Handle the request. */
    switch(cmd)
    {
        case POWER_IC_IOCTL_PERIPH_SET_BLUETOOTH_ON:
            retval = power_ic_periph_set_bluetooth_on(data);
            break;

        case POWER_IC_IOCTL_PERIPH_SET_FLASH_CARD_ON:
            retval = power_ic_periph_set_flash_card_on(data);
            break;
                
        case POWER_IC_IOCTL_PERIPH_SET_VIBRATOR_LEVEL:
            retval = power_ic_periph_set_vibrator_level(data);
            break;

        case POWER_IC_IOCTL_PERIPH_SET_VIBRATOR_ON:
            retval = power_ic_periph_set_vibrator_on(data);
            break;

        case POWER_IC_IOCTL_PERIPH_SET_WLAN_ON:
            retval = power_ic_periph_set_wlan_on(data);
            break;
	    
        case POWER_IC_IOCTL_PERIPH_SET_WLAN_LOW_POWER_STATE_ON:
            retval = power_ic_periph_set_wlan_low_power_state_on();
            break;
            
        case POWER_IC_IOCTL_PERIPH_SET_CAMERA_ON:
            retval = power_ic_periph_set_camera_on(data);
            break;

        default: /* This shouldn't be able to happen, but just in case... */
            tracemsg(_k_d("=> 0x%X unsupported peripheral ioctl command"), (int) cmd);
            retval = -EINVAL;
            break;
    }

    return retval;
}
コード例 #5
0
ファイル: rc.c プロジェクト: gamma62/eda
/*
** reload_macros - drop all macros and process macrofile again
*/
int
reload_macros (void)
{
	int ret=0;

	drop_macros();

	ret = process_macrofile(0);
	if (ret) {
		tracemsg ("loading macros failed (%d)", ret);
	} else {
		tracemsg ("%d macros loaded", MLEN);
	}

	return ret;
}
コード例 #6
0
/*!
 * @brief Event handler for the power IC VBUS, SE1, and ID interrupts on SCMA11-Bute platforms
 *
 * This function is the event handler for the power IC VBUS,SE1 and ID interrupts.
 * When the events occur, the job of the interrupt handler is to ensure that
 * the event is reported to the User Space using the poll system call.  
 * This is accomplished through the following mechanism:
 *
 *   - Update the power_ic_event_int variable containing the type of events that
 *     occur before the User Space read it.
 *
 *   - Wake up the power_ic_poll function by updating the power_ic_event_int and
 *     waking up the power_ic_event_int_wait_queue wait queue. 
 *
 * @param event parameter indicating which even occurred
 *
 * @return 1, indicating that the event has been handled
 */
static int emu_glue_int_handler(POWER_IC_EVENT_T event)
{
    tracemsg(_k_d("EMU: emu_glue_int_handler: interrupt received for 0x%x event"),event);

    /* take mutex */
    down(&emu_proc_event_int_mutex);
    
    /* Update power_ic_event_int variable */
    switch (event)
    {
        case POWER_IC_EVENT_ATLAS_USBI: 
            emu_proc_event_int |= POWER_IC_EVENT_INT_VBUS;
            break; 
        case POWER_IC_EVENT_ATLAS_IDI:
            emu_proc_event_int |= POWER_IC_EVENT_INT_ID;
            break; 
        case POWER_IC_EVENT_ATLAS_SE1I:
            emu_proc_event_int |= POWER_IC_EVENT_INT_SE1;
            break;
        default:
            break;
    }
    
    /* Release mutex and wake up poll function */
    emu_proc_event_int_flag = true;
    up(&emu_proc_event_int_mutex);
    wake_up_interruptible(&emu_proc_event_int_wait_queue); 
    return 1;
}
コード例 #7
0
ファイル: iolayer.cpp プロジェクト: nihilus/idaperl
bool enablestderr(bool bNewState)
{
    tracemsg("enablestderr\n");
    bool bOldState= g_stderrenabled;
    g_stderrenabled= bNewState;
    return bOldState;
}
コード例 #8
0
/*!
 * @brief Used to determine what type of PPD this is.
 *
 * The event handler function reads the state of the D+ and D- lines to determine
 * what type of accessory is connected. The state is then changed to the
 * Connected state along with an indication of 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 ppd_identify_handler(int *polling_interval)
{
    *polling_interval = EMU_POLL_CONTINUE;
    
    switch (get_bus_state(EMU_BUS_SIGNAL_DP_DM))
    {
        case EMU_BUS_SIGNAL_STATE_DP_DM_10:
            emu_current_device = MOTO_ACCY_TYPE_HEADSET_EMU_MONO;
            return EMU_STATE_CONNECTED__HEADSET;
            break;
            
        case EMU_BUS_SIGNAL_STATE_DP_DM_00:
            tracemsg(_k_d("The headset is detected as EMU ST headset"));
            emu_current_device = MOTO_ACCY_TYPE_HEADSET_EMU_STEREO;
            return EMU_STATE_CONNECTED__HEADSET;
            break;
            
        case EMU_BUS_SIGNAL_STATE_DP_DM_01:
        case EMU_BUS_SIGNAL_STATE_DP_DM_11:
        default:
            emu_current_device = MOTO_ACCY_TYPE_NOT_SUPPORTED;
            return EMU_STATE_CONNECTED__NOT_SUPPORTED;
            break;
    }
}
コード例 #9
0
/*!
 * @brief Enables power to the PPD accessory, then wait for the VBUS line to settle
 *
 * The purpose of this state is to identify the type of phone-powered accessory
 * attached to the phone.  This identification is performed using the following
 * steps:
 *   1.Enable power to the accessory
 *   2.Wait 200 milliseconds.
 *   3.Read the state of the D+ and D- lines.
 * The state of the D+ and D- lines indicates the type of accessory that is
 * connected based on the following table:
 *
 *   D+ D- Accessory       
 *   0  0  Unknown     
 *   0  1  Unknown     
 *   1  0  EMU mono headset    
 *   1  1  Unknown   
 * Table 4: Phone-powered accessory identification
 *
 * The entry function for the state will enable the power to the accessory and
 * configure the timer to expire after 200 milliseconds.  This will cause the
 * event handler function to be called after this delay to check the state of the
 * D+ and D- lines.
 *
 * @param prev_state the previous EMU state
 * @param polling_interval a return parameter that holds the "polling rate"
 */
void pre_ppd_identify_enter(EMU_STATE_T prev_state, int *polling_interval)
{
    tracemsg(_k_d("EMU: pre_ppd_identify_enter: EMU_DEV_TYPE_PPD"));
     /* Power VBUS */
    EMU_SET_REVERSE_MODE(ENABLE);
    
    /* Set timer to wait for D+ and D- lines to stabilize */
    *polling_interval = EMU_POLL_REV_MODE_DELAY;
}
コード例 #10
0
ファイル: iolayer.cpp プロジェクト: nihilus/idaperl
void init_idamsg_io(pTHX)
{
    tracemsg("init_idamsg_io1\n");
    PerlIO_define_layer(aTHX_ &PerlIO_idamsg);

//binmode ":idamsg", stdout;
    PerlIO_push(aTHX_ PerlIO_stdout(), &PerlIO_idamsg, "a", NULL);
//binmode ":idamsg", stderr;
    PerlIO_push(aTHX_ PerlIO_stderr(), &PerlIO_idamsg, "a", NULL);
}
コード例 #11
0
ファイル: clireg.cpp プロジェクト: nihilus/idaperl
bool idaapi cli_execute(const char *line)
{
    tracemsg("cli: '%s'\n", line);
    std::string errbuf; errbuf.resize(1024);
    if (!cliinterp->exec(line, &errbuf[0], errbuf.size())) {
        msg("%s\n", errbuf.c_str());

        // todo: add support for multiline perl: first only syntax check, return false until syntax is ok.
    }
    return true;
}
コード例 #12
0
/*!
 * @brief This utility function sets the audio mode in Atlas and stereo emu headset
 *        pull up.
 *
 * @param mode - The headset mode
 *
 */
void emu_util_set_emu_headset_mode(MOTO_ACCY_HEADSET_MODE_T mode)
{
    switch(mode)
    {   
        case MOTO_ACCY_HEADSET_MODE_NONE:
            EMU_SET_REVERSE_MODE(false);

            /* Don't allow power management to suspend the phone while waiting for VBUS to settle. */
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] |= POWER_IC_EMU_REV_MODE_SLEEP;
            
            /* mdelay must be used here because the delay cannot be allowed to be longer than 20 ms. */
            mdelay(12);
            
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] &= ~(POWER_IC_EMU_REV_MODE_SLEEP);
            
            EMU_SET_EMU_CONN_MODE(POWER_IC_EMU_CONN_MODE_USB);
            EMU_SET_HEADSET_PULL_UP(0);
            /*Following is the work around for the emu headset send/end key*/
            EMU_SET_HS_SEND_END_REGS(1);
            EMU_SET_VUSB_INPUT_SOURCE(EMU_VREG_IN_VINBUS);
            break;
        
        case MOTO_ACCY_HEADSET_MODE_MONO:
            EMU_SET_VUSB_INPUT_SOURCE(EMU_VREG_IN_BPLUS);
            EMU_SET_HS_SEND_END_REGS(0);
            EMU_SET_EMU_CONN_MODE(POWER_IC_EMU_CONN_MODE_MONO_AUDIO);
            EMU_SET_HEADSET_PULL_UP(0);
            
            /* Don't allow power management to suspend the phone while waiting for D- to settle */
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] |= POWER_IC_EMU_DMINUS_MONO_SLEEP;
            msleep(10);
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] &= ~(POWER_IC_EMU_DMINUS_MONO_SLEEP);
            
            EMU_SET_REVERSE_MODE(true);
            break;
            
        case MOTO_ACCY_HEADSET_MODE_STEREO:
            EMU_SET_VUSB_INPUT_SOURCE(EMU_VREG_IN_BPLUS);
            EMU_SET_HS_SEND_END_REGS(0);
            EMU_SET_EMU_CONN_MODE(POWER_IC_EMU_CONN_MODE_STEREO_AUDIO);
            EMU_SET_HEADSET_PULL_UP(1);
            
            /* Don't allow power management to suspend the phone while waiting for D- to settle */
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] |= POWER_IC_EMU_DMINUS_STEREO_SLEEP;
            msleep(10);
            power_ic_pm_suspend_mask_tbl[POWER_IC_PM_MISC_SLEEPS] &= ~(POWER_IC_EMU_DMINUS_STEREO_SLEEP);
            
            EMU_SET_REVERSE_MODE(true);
            break;
        
        default:
            tracemsg(_k_d("EMU: Audio Mode %d not supported"), mode);
    }
}
コード例 #13
0
/*!
 * @brief Initializes the EMU Glue utils
 *
 * The function performs the initialization of the EMU glue utils variables and register handler
 * to the Power IC EMU related interrupts
 */
int __init emu_glue_utils_init(void)
{
    struct proc_dir_entry * emu_proc;

    tracemsg(_k_d("EMU: emu_glue_utils_init: initializing kernel EMU glue utils"));

    /* configure D+/D- lines and cradle detect line */
    power_ic_gpio_emu_config();

    /* Create emu proc entry */
    emu_proc = create_proc_entry("emu", S_IRUGO | S_IWUGO, NULL);
    if (emu_proc == NULL)
    {
        tracemsg(_k_d(KERN_ERR "Unable to create EMU proc entry in /proc.\n"));
        return -ENOMEM;
    }

    /* Set the proc fops */
    emu_proc->proc_fops = (struct file_operations *)&emu_proc_fops;
 
    /* Initialize variables */ 
    emu_proc_event_int = 0;
    emu_proc_event_int_flag = false;
    power_ic_emu_hw_locked = false;
    emu_proc_opened = false;
    audio_config.headset_mode = MOTO_ACCY_HEADSET_MODE_NONE;
    audio_config.conn_mode = POWER_IC_EMU_CONN_MODE_USB;
    audio_config.id_pull_down = 0;
    
    /* register the light usb driver int */
    power_ic_event_subscribe(EMU_INT_VBUS,usb_detection_int_handler);

    tracemsg(_k_d("USB DET: Start light driver thread"));

    /* Create USB detection thread */
    kernel_thread(usb_detection_state_machine_thread, NULL, 0);

    /* Init ok */
    return 0;
}
コード例 #14
0
ファイル: rtc.c プロジェクト: muromec/linux-ezxdev
int rtc_ioctl(unsigned int cmd, unsigned long arg)
{
    struct timeval power_ic_time;
    struct timeval * usr_spc_time_val = (struct timeval *)arg;
    int err = 0;

    /* Handle the request. */
    switch(cmd)
    {
        case POWER_IC_IOCTL_GET_TIME:
	    /* Read the TOD and DAY registers and set the data in the timeval
	       structure to the format the Linux uses.*/
	    err = power_ic_rtc_get_time(&power_ic_time);
	    if(copy_to_user(usr_spc_time_val, &power_ic_time, sizeof(power_ic_time)))
	    {
	       err = -EFAULT;
	    }
	    break;
        case POWER_IC_IOCTL_GET_ALARM_TIME:
	    /* Read the TODA and DAYA registers and set the data in the timeval
	       structure to the format the Linux uses.*/
	    err = power_ic_rtc_get_time_alarm(&power_ic_time);
	    if(copy_to_user(usr_spc_time_val, &power_ic_time, sizeof(power_ic_time)))
	    {
	       err = -EFAULT;
	    }
	    break;
        case POWER_IC_IOCTL_SET_TIME:
	    /* Write to  the TOD and DAY registers based on the data in the timeval struct */
	    if(copy_from_user(&power_ic_time,usr_spc_time_val, sizeof(power_ic_time)))
	    {
	       err = -EFAULT;
	    }
	    err = power_ic_rtc_set_time(&power_ic_time);
	    break;	
        case POWER_IC_IOCTL_SET_ALARM_TIME:
	    /* Write to  the TODA and DAYA registers based on the data in the timeval struct */
	    if (copy_from_user(&power_ic_time,usr_spc_time_val,sizeof(power_ic_time)))
	    {
	       err = -EFAULT;
	    }	      
	    err = power_ic_rtc_set_time_alarm(&power_ic_time);
	    break;	
        default: /* This shouldn't be able to happen, but just in case... */
            tracemsg(_k_d("0x%X unsupported ioctl command"), (int) cmd);
            err =  -ENOTTY;
	    break;
    }
    
    return err;
}
コード例 #15
0
ファイル: charger.c プロジェクト: muromec/linux-ezxdev
/*!
 * @brief Sets the power path.
 *
 * This function configures the path used to supply current from the charger. In
 * dual-path mode, the charger is connected to the phone's supply and can operate
 * the phone without a battery so long as the current drawn isn't too high. In 
 * current-share mode, a battery must be present for the phone to operate.
 *
 * @param        path       New setting for power path.
 *
 * @pre The power path must be set to dual-path prior to enabling the trickle
 * charger.
 *
 * @return returns 0 if successful.
 */
int power_ic_charger_set_power_path(POWER_IC_CHARGER_POWER_PATH_T path)
{
    /* Both FET override and FET control are used to control path. */
    int mask = EMU_FET_OVRD_MASK | EMU_FET_CTRL_MASK;
    int setup;
    
    switch(path)
    {
        /* Hardware-controlled dual-path mode. */
        case POWER_IC_CHARGER_POWER_DUAL_PATH:
            setup = 0;
            break;
        
        /* Hardware-controlled current-share mode. */    
        case POWER_IC_CHARGER_POWER_CURRENT_SHARE:
            setup = EMU_FET_CTRL_MASK;
            break;
                        
        /* Software-overridden dual-path mode. */    
        case POWER_IC_CHARGER_POWER_DUAL_PATH_SW_OVERRIDE:
            setup = EMU_FET_OVRD_MASK;
            break;   
                 
        /* Software-overridden current-share mode. */
        case POWER_IC_CHARGER_POWER_CURRENT_SHARE_SW_OVERRIDE:
            setup = EMU_FET_OVRD_MASK | EMU_FET_CTRL_MASK;
            break;
            
        default:
            tracemsg(_k_d("   power path %d is invalid."), path);
            return -EINVAL;
    }
    
    tracemsg(_k_a("########################## Charger: setting power path 0x%X (masked with 0x%X)"), setup, mask);
    
    return(power_ic_set_reg_mask(POWER_IC_REG_EOC_POWER_CONTROL_0, mask, setup));
}
コード例 #16
0
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;
}
コード例 #17
0
ファイル: rtc.c プロジェクト: muromec/linux-ezxdev
int power_ic_rtc_set_time(struct timeval *power_ic_time)
{
    int err = 0;
    if (power_ic_time->tv_usec > 500000)
    {
      power_ic_time->tv_sec += 1;
    }
    err = power_ic_set_reg_value(RTC_TOD_REG,POWER_IC_TIME_REG_BIT,
				 power_ic_time->tv_sec % POWER_IC_NUM_SEC_PER_DAY,  POWER_IC_TOD_NUM_BITS );
    err = power_ic_set_reg_value(RTC_DAY_REG,POWER_IC_TIME_REG_BIT,
				 power_ic_time->tv_sec / POWER_IC_NUM_SEC_PER_DAY, POWER_IC_DAY_NUM_BITS);
    tracemsg(_k_d("Set RTC Time \n RTC_TOD = %d \n RTC_DAY = %d \n tv_sec = %d Error = %d \n"),((int)power_ic_time->tv_sec % POWER_IC_NUM_SEC_PER_DAY) , 
	     ((int)power_ic_time->tv_sec / POWER_IC_NUM_SEC_PER_DAY),((int)power_ic_time->tv_sec), err );
    return err;
}
コード例 #18
0
ファイル: iolayer.cpp プロジェクト: nihilus/idaperl
SSize_t PerlIOidamsg_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
{
    tracemsg("PerlIOidamsg_write\n");
    if (!g_stderrenabled)
        return count;

    SSize_t total= 0;
    Size_t ofs= 0;
    while (ofs<count) {
        Size_t printed= msg("%.*s", (int)(count-ofs), (const char*)vbuf+ofs);
        ofs += printed;
        if (printed==0)
            break;
    }
    return total;
}
コード例 #19
0
static int emu_proc_release(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;
    }

    /* Reset the opened state */
    emu_proc_opened = false;

    /* Release mutex */
    up(&emu_proc_opened_mutex);

    return 0;
}
コード例 #20
0
ファイル: rtc.c プロジェクト: muromec/linux-ezxdev
int power_ic_rtc_get_time_alarm(struct timeval *power_ic_time)
{
    int toda_reg_val = 0;
    int daya_reg_val = 0;
    int err = 0;
   
    err = power_ic_get_reg_value(RTC_TODA_REG, POWER_IC_TIME_REG_BIT, 
				 &toda_reg_val, POWER_IC_TOD_NUM_BITS);
    err = power_ic_get_reg_value(RTC_DAYA_REG, POWER_IC_TIME_REG_BIT,
				 &daya_reg_val, POWER_IC_DAY_NUM_BITS);

    power_ic_time->tv_sec = toda_reg_val + daya_reg_val * POWER_IC_NUM_SEC_PER_DAY;
    power_ic_time->tv_usec = 0;
 
    tracemsg(_k_d("Get RTC Alarm Time \n RTC_TODA = %d \n RTC_DAYA = %d \n tv_sec = %d Error = %d \n"), toda_reg_val, 
	     daya_reg_val,(int)power_ic_time->tv_sec, err );
    return err;
}
コード例 #21
0
ファイル: rtc.c プロジェクト: muromec/linux-ezxdev
int power_ic_rtc_set_time_alarm(struct timeval *power_ic_time)
{

    int err = 0;
    
    if (power_ic_time->tv_usec > 500000)
    {
       power_ic_time->tv_sec += 1;
    }
    err = power_ic_set_reg_value(RTC_TODA_REG,POWER_IC_TIME_REG_BIT,
				 power_ic_time->tv_sec % POWER_IC_NUM_SEC_PER_DAY,  POWER_IC_TOD_NUM_BITS );
    err = power_ic_set_reg_value(RTC_DAYA_REG,POWER_IC_TIME_REG_BIT,
				 power_ic_time->tv_sec / POWER_IC_NUM_SEC_PER_DAY, POWER_IC_DAY_NUM_BITS);

    err |= power_ic_event_unmask(RTC_TODA_EVENT);
    
    tracemsg(_k_d("Set RTC Alarm Time \nRTC_TODA = %d \n RTC_DAYA = %d \n tv_sec = %d Error = %d \n"),(int)power_ic_time->tv_sec % POWER_IC_NUM_SEC_PER_DAY , 
	     (int)power_ic_time->tv_sec / POWER_IC_NUM_SEC_PER_DAY,(int)power_ic_time->tv_sec, err );
    return err;
}
コード例 #22
0
/*!
 * @brief Used to determine what type of PPD this is initially.
 *
 * The event handler function reads the state of the D+ and D- lines to determine
 * what type of accessory is connected. The state is then changed to the
 * Connected state along with an indication of 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 pre_ppd_identify_handler(int *polling_interval)
{
    *polling_interval = EMU_POLL_CONTINUE;
    switch (get_bus_state(EMU_BUS_SIGNAL_DP_DM))
    {
        case EMU_BUS_SIGNAL_STATE_DP_DM_10:   

            tracemsg(_k_d("Set the GPIO for ST headset"));
            EMU_SET_HEADSET_PULL_UP(ENABLE);
            return EMU_STATE_CONNECTING__PPD_IDENTIFY;
            break;
              
        case EMU_BUS_SIGNAL_STATE_DP_DM_00:
        case EMU_BUS_SIGNAL_STATE_DP_DM_01:
        case EMU_BUS_SIGNAL_STATE_DP_DM_11:
        default:
            emu_current_device = MOTO_ACCY_TYPE_NOT_SUPPORTED;
            return EMU_STATE_CONNECTED__NOT_SUPPORTED;
            break;
    }
}
コード例 #23
0
/*!
 * @brief the read() handler for the EMU power IC proc device node  - for SCMA11 and BUTE platform only.
 *
 * This function implements the read() system call on the power IC device.
 *
 * @param        file        file pointer
 * @param        buf         data
 * @param        count       data size
 * @param        ppos        position unused.
 * 
 *
 * @return 0 if succesful
 */
ssize_t emu_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{   
    int retval = 0;
    /* If there isn't space in the buffer for the results, return a failure. Do not 
     * consider the process complete if this happens as the results are still available. */
    if(count < sizeof(emu_proc_event_int))
    {
        return -EFBIG;
    }
    
    /* take mutex */
    if(down_interruptible(&emu_proc_event_int_mutex))
    {
        tracemsg(_k_d("process received signal while waiting for power ic int event  mutex. Exiting."));
        return -EINTR;
    }
        
    /* Copy the results back to user-space. */
    if( !(copy_to_user((int *)buf, (void *)&emu_proc_event_int, sizeof(emu_proc_event_int))) )
    {
        /* Data was copied successfully. */
        retval = sizeof(emu_proc_event_int);
    }
    else
    {
        /* release mutex */
        up(&emu_proc_event_int_mutex);
        return -EFAULT;
    }
    
    /* Clear variable and release mutex */
    emu_proc_event_int_flag = false;
    emu_proc_event_int = 0;
    up(&emu_proc_event_int_mutex);

    return retval;
}
コード例 #24
0
ファイル: timing.c プロジェクト: muromec/linux-ezxdev
/*!
 * @brief Displays rate info about the timer.
 *
 * This function prints a load of information about the rate of a timer's start times 
 * to the console.
 *
 * @param     timer     The timer for which info should be shown.
 * @param     show_all  After the average, etc. show all periods, 1 per line. Set false if
 *                      only a summary of the times is needed.
 *
 * @return 0 if successful
 */
void timing_print_rate_info(TIMING_TIMER_T * timer, bool show_all)
{
    int i;
    struct timeval lowest_elapsed_time = {100000000, 0};
    int lowest_elapsed_time_index = 0;
    struct timeval highest_elapsed_time = {0, 0};
    int highest_elapsed_time_index = 0;
    int rate;
    unsigned long std_dev = 0;
    int elapsed_usec;
    int average_usec;
    
    struct timeval elapsed_time = {0, 0};
    struct timeval total_elapsed_time = {0, 0};
    struct timeval average_elapsed_time = {0, 0};
    struct timeval delta;
    
    /* Since we are looking at the start times for rate information, we need two times stored
     * for one period, three times for two periods, etc. */
    int num_periods = timer->num_times_recorded - 1;
    
    /* There's no point in continuing if there is insufficient information available
     * to show period information. */
    if(num_periods <= 0)
    {
        tracemsg(_a("Rate info: %d timer start/stops is insufficient for rate analysis."), 
                    timer->num_times_recorded);
        return;
    }
    
    tracemsg(_a("Rate info: number of periods captured: %d"), num_periods);
    
    /* Go figure out some info about the timers captured. */
    for(i = 0; i < num_periods; i++)
    {
        /* Get elapsed_time between the two start times. */
        subtract(&(timer->times[i].start_time), &(timer->times[i+1].start_time), &elapsed_time);
                                   
        /* Check elapsed time against highest. */
        if(greater_than(&elapsed_time, &highest_elapsed_time))
        {
            highest_elapsed_time.tv_sec = elapsed_time.tv_sec;
            highest_elapsed_time.tv_usec = elapsed_time.tv_usec;
            highest_elapsed_time_index = i;
        }
            
        /* Check elapsed time against lowest. */
        if(less_than(&elapsed_time, &lowest_elapsed_time))
        {
            lowest_elapsed_time.tv_sec = elapsed_time.tv_sec;
            lowest_elapsed_time.tv_usec = elapsed_time.tv_usec;
            lowest_elapsed_time_index = i;
        }
            
        /* Add this elapsed time to total. */
        add(&elapsed_time, &total_elapsed_time, &total_elapsed_time);
            
        if(false)
        {
            tracemsg(_a("      result %4d: elapsed time %2lds, %6ld usec"), 
                         i, elapsed_time.tv_sec, elapsed_time.tv_usec);
        }
    }
            
    /* Figure out the average elapsed time. */
    average(&total_elapsed_time, timer->num_times_recorded, &average_elapsed_time);
    rate = rate_per_sec(&average_elapsed_time);
            
    tracemsg(_a(" Average period %2lds, %6ld usec (%d/sec)"), 
                average_elapsed_time.tv_sec, average_elapsed_time.tv_usec, rate);
                
    /* Figure out standard deviation for the set of periods. */
    average_usec = USECS(average_elapsed_time);
    for(i = 0; i < num_periods; i++)
    {
        /* Get elapsed_time between the two start times. */
        subtract(&(timer->times[i].start_time), &(timer->times[i+1].start_time), &elapsed_time);
        elapsed_usec = USECS(elapsed_time);
        std_dev += ((elapsed_usec - average_usec) * (elapsed_usec - average_usec));
    }
    
    std_dev = std_dev / i; /* Rounding error shouldn't matter too much.*/
    std_dev = square_root(std_dev);
    tracemsg(_a(" Approx std dev      %6ld usec"), std_dev);
                       
    /* For highest time recorded, figure out delta between this and average. */
    subtract(&average_elapsed_time, &highest_elapsed_time, &delta);
    rate = rate_per_sec(&highest_elapsed_time);
    tracemsg(_a(" Highest period %2lds, %6ld usec (%3d/sec, delta from avg %lds, %6ld us, result %d)"), 
                highest_elapsed_time.tv_sec, highest_elapsed_time.tv_usec, 
                rate, delta.tv_sec, delta.tv_usec, 
                highest_elapsed_time_index);
                       
    /* Same for lowest. */
    subtract(&lowest_elapsed_time, &average_elapsed_time, &delta);
    rate = rate_per_sec(&lowest_elapsed_time);          
    tracemsg(_a("  Lowest period %2lds, %6ld usec (%3d/sec, delta from avg %lds, %6ld us, result %d)"), 
                lowest_elapsed_time.tv_sec, lowest_elapsed_time.tv_usec, 
                rate, delta.tv_sec, delta.tv_usec, 
                lowest_elapsed_time_index);
    
               
    /* If told to show everything, dump all of the values to text in units of microseconds. 
     * Put commas before and after each value to make this easier to import into excel or
     * whatever as CSV as there's some sort of timestamp prepended to every printk these days... */ 
    if(show_all)
    {
        tracemsg(_a(""));
        tracemsg(_a(" All periods recorded (usecs):")); 
        for(i = 0; i < num_periods; i++)
        {
            subtract(&(timer->times[i].start_time), &(timer->times[i+1].start_time), &elapsed_time);
            tracemsg(",%ld,\n", USECS(elapsed_time));
        }
    }
        
} /* End of rate info. */
コード例 #25
0
ファイル: timing.c プロジェクト: muromec/linux-ezxdev
/*!
 * @brief Displays info about the timer.
 *
 * This function prints a load of information about the captured timing information 
 * to the console.
 *
 * @param     timer     The timer for which info should be shown.
 * @param     show_all  After the average, etc. show all elapsed times, 1 per line. 
 *                      Set false if only a summary of the times is needed.
 *
 * @return 0 if successful
 */
void timing_print_info(TIMING_TIMER_T * timer, bool show_all)
{
    int i;
    struct timeval lowest_elapsed_time = {100000000, 0};
    int lowest_elapsed_time_index = 0;
    struct timeval highest_elapsed_time = {0, 0};
    int highest_elapsed_time_index = 0;
    
    unsigned long std_dev = 0;
    int elapsed_usec;
    int average_usec;
    
    struct timeval elapsed_time = {0, 0};
    struct timeval total_elapsed_time = {0, 0};
    struct timeval average_elapsed_time = {0, 0};
    struct timeval delta;
    
    if(timer != NULL)
    {
        if(timer->num_times_recorded == 0)
        {
            tracemsg(_a("\nTiming: no results captured."));  
            return;
        }
        
        tracemsg(_a("Timing: number of results captured: %d"), timer->num_times_recorded);
        
        /* Go figure out some info about the timers captured. */
        for(i = 0; i < timer->num_times_recorded; i++)
        {
            /* Get elapsed_time. */
            subtract(&(timer->times[i].start_time), &(timer->times[i].stop_time), &elapsed_time);
                                   
            /* Check elapsed time against highest. */
            if(greater_than(&elapsed_time, &highest_elapsed_time))
            {
                highest_elapsed_time.tv_sec = elapsed_time.tv_sec;
                highest_elapsed_time.tv_usec = elapsed_time.tv_usec;
                highest_elapsed_time_index = i;
            }
            
            /* Check elapsed time against lowest. */
            if(less_than(&elapsed_time, &lowest_elapsed_time))
            {
                lowest_elapsed_time.tv_sec = elapsed_time.tv_sec;
                lowest_elapsed_time.tv_usec = elapsed_time.tv_usec;
                lowest_elapsed_time_index = i;
            }
            
            /* Add this elapsed time to total. */
            add(&elapsed_time, &total_elapsed_time, &total_elapsed_time);
            
            if(show_all)
            {
                tracemsg(_a("      result %4d: elapsed time %2lds, %6ld usec"), 
                       i, elapsed_time.tv_sec, elapsed_time.tv_usec);
            }
        }
        
        /* Figure out the average elapsed time. */
        average(&total_elapsed_time, timer->num_times_recorded, &average_elapsed_time);
                               
        tracemsg(_a("Average elapsed %2lds, %6ld usec"), 
                       average_elapsed_time.tv_sec, average_elapsed_time.tv_usec);
                       
        /* Figure out standard deviation for the set of elapsed times. This needs to be
         * done after the average is calculated. */
        average_usec = USECS(average_elapsed_time);
        for(i = 0; i < timer->num_times_recorded; i++)
        {
            /* Get elapsed_time between the start and stop. */
            subtract(&(timer->times[i].start_time), &(timer->times[i].stop_time), &elapsed_time);
            elapsed_usec = USECS(elapsed_time);
            std_dev += ((elapsed_usec - average_usec) * (elapsed_usec - average_usec));
        }
    
        std_dev = std_dev / i; /* Rounding error shouldn't matter too much.*/
        std_dev = square_root(std_dev);
        tracemsg(_a(" Approx std dev      %6ld usec"), std_dev);
                       
        /* For highest time recorded, figure out delta between this and average. */
        subtract(&average_elapsed_time, &highest_elapsed_time, &delta);
         
        tracemsg(_a("Highest elapsed %2lds, %6ld usec (delta from avg %lds, %6ldus, result %d)"), 
                       highest_elapsed_time.tv_sec, highest_elapsed_time.tv_usec, 
                       delta.tv_sec, delta.tv_usec, 
                       highest_elapsed_time_index);
                       
        /* Same for lowest. */
        subtract(&lowest_elapsed_time, &average_elapsed_time, &delta);
                       
        tracemsg(_a(" Lowest elapsed %2lds, %6ld usec (delta from avg %lds, %6ldus, result %d)"), 
                       lowest_elapsed_time.tv_sec, lowest_elapsed_time.tv_usec, 
                       delta.tv_sec, delta.tv_usec, 
                       lowest_elapsed_time_index);
    }
}
コード例 #26
0
ファイル: tracing.c プロジェクト: ErisBlastar/osfree
int intertrace( tsd_t *TSD )
{
   streng *str=NULL;
   int retvalue1,rc;
   tra_tsd_t *tt;

   tt = (tra_tsd_t *)TSD->tra_tsd;

   if ( tt->intercount )
   {
      tt->intercount -= 1;
      if ( tt->intercount == 0 )
      {
         tt->quiet = 0;
         tt->traceflag = 0;
      }
      else
         return 0;
   }

   if ( tt->traceflag )
      return 0;

   if ( tt->notnow == 1 )
   {
      tt->notnow = 2;
      return 0;
   }
   else if ( tt->notnow == 2 )
   {
      tt->notnow = 0;
      tracemsg( TSD );
   }
   tt->traceflag = 1;
   retvalue1 = -1;

   for ( ; retvalue1 < 0; )
   {
      rc = HOOK_GO_ON;
      if ( TSD->systeminfo->hooks & HOOK_MASK( HOOK_TRCIN ) )
         rc = hookup_input( TSD, HOOK_TRCIN, &str );

      if ( rc == HOOK_GO_ON )
         str = readkbdline( TSD );

      if ( str->len == 0 )
      {
         tt->traceflag = 0;
         retvalue1 = 0;
      }

      if ( ( Str_len( str ) == 1 ) && (str->value[0] == '=' ) )
      {
         tt->traceflag = 0;
         retvalue1 = 1;
      }
      else if ( str->len )
      {
         dointerpret( TSD, str );
         if ( !TSD->systeminfo->interactive )
         {
            tt->intercount = tt->quiet = 0;
            return 0;
         }
         if ( tt->intercount )
         {
            if ( tt->quiet )
               tt->traceflag = 1;
            else
               tt->traceflag = 0;
            return 0;
         }
      }
   }

   return retvalue1;
}
コード例 #27
0
ファイル: charger.c プロジェクト: muromec/linux-ezxdev
/*!
 * @brief Sets the charge voltage.
 *
 * This function sets the maximum voltage that the battery will charged up to.
 *
 * @param        charge_voltage       Maximum charge voltage to be set.
 *
 * @return returns 0 if successful.
 */
int power_ic_charger_set_charge_voltage(int charge_voltage)
{   
    tracemsg(_k_d("Charger: setting VCHRG 0x%X"), charge_voltage);
    return(power_ic_set_reg_mask(POWER_IC_REG_EOC_POWER_CONTROL_0, EMU_VCHRG_MASK, charge_voltage));
}
コード例 #28
0
static int emu_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    unsigned int ret_val = 0;
    
    POWER_IC_EMU_GLUE_READ_SENSE_T read_sense; 
    POWER_IC_EMU_GLUE_TRANSCEIVER_PARAMS_T trans_params;
    POWER_IC_FET_CONTROL_T fet_ctrl;

    /* prev lockout status */
    static bool prev_emu_hw_lockout_state = false;

    /* what devices were connected before lockout */
    static MOTO_ACCY_MASK_T connected_device_before_lock = 0;
    MOTO_ACCY_MASK_T connected_device;
    
    /* Get the actual command from the ioctl request. */
    unsigned int cmd_num = _IOC_NR(cmd);
    
    if ((cmd_num >= POWER_IC_IOC_CMD_EMU_GLUE_BASE) && (cmd_num <= POWER_IC_IOC_CMD_EMU_GLUE_LAST_CMD))
    { 
        tracemsg(_k_d("EMU GLUE control ioctl(), request 0x%X (cmd 0x%X)"),(int) cmd, _IOC_NR(cmd));

        /* Handle the request. */
        switch(cmd)
        {
            case POWER_IC_IOCTL_CMD_EMU_GLUE_READ_SENSE:
                /* Fetch the data passed from user space. */
                if(copy_from_user((void *)&read_sense, (void *)arg, sizeof(read_sense)) != 0)
                {
                    tracemsg(_k_d("error copying data from user space."));
                    ret_val = -EFAULT;
                }  
                else
                {
                    /* Read the sense and clear the interrupt if requested */
                    read_sense.sense = emu_glue_read_sense(read_sense.clear_int_flags);

                    /* Only the sense value read needs to be sent back to the caller. */
                    if(put_user(read_sense.sense,&(((POWER_IC_EMU_GLUE_READ_SENSE_T *)arg)->sense)) != 0)
                    {
                        tracemsg(_k_d("error copying read bits to user space."));
                        ret_val = -EFAULT;
                    }
                }
                break;
                
            case POWER_IC_IOCTL_CMD_EMU_GLUE_LOCKOUT_CHANGES:
                power_ic_emu_hw_locked = (bool)(arg == 0 ? 0 : 1);
                 
                if (power_ic_emu_hw_locked)
                {
                    /* Make sure the hardware is not already locked */
                    if (prev_emu_hw_lockout_state == false)
                    {
                        /* If the EMU hardware needs to be locked, keep track of
                           the currently connected accessory */
                        connected_device_before_lock = moto_accy_get_all_devices();
                    }
                }
                else
                {                   
                    /* If the EMU hardware was previously locked but is now unlocked the accessory may need
                       to be reconfigured. */
                    if (prev_emu_hw_lockout_state == true)
                    {
                        connected_device = moto_accy_get_all_devices();
                        
                        if (connected_device_before_lock == connected_device)
                        {
                            if ((ACCY_BITMASK_ISSET(connected_device, MOTO_ACCY_TYPE_HEADSET_EMU_MONO)) ||
                                (ACCY_BITMASK_ISSET(connected_device, MOTO_ACCY_TYPE_HEADSET_EMU_STEREO)))
                            {
                                audio_config.id_pull_down = 0;
                                audio_config.conn_mode = 0;
                                emu_util_set_emu_headset_mode(audio_config.headset_mode);
                            }
                            else if ((ACCY_BITMASK_ISSET(connected_device, MOTO_ACCY_TYPE_CARKIT_MID)) ||
                                     (ACCY_BITMASK_ISSET(connected_device, MOTO_ACCY_TYPE_CARKIT_FAST)))
                            {
                                audio_config.headset_mode = MOTO_ACCY_HEADSET_MODE_NONE;
                                EMU_SET_EMU_CONN_MODE(audio_config.conn_mode);
                                EMU_SET_ID_PULL_DOWN(audio_config.id_pull_down);
                            }
                            else
                            {
                                audio_config.headset_mode = MOTO_ACCY_HEADSET_MODE_NONE;
                                audio_config.conn_mode = POWER_IC_EMU_CONN_MODE_USB;
                                audio_config.id_pull_down = 0;  
                            }
                        }
                        else
                        {
                            audio_config.headset_mode = MOTO_ACCY_HEADSET_MODE_NONE;
                            audio_config.conn_mode = POWER_IC_EMU_CONN_MODE_USB;
                            audio_config.id_pull_down = 0;  
                        }
                    }
                }

                prev_emu_hw_lockout_state = power_ic_emu_hw_locked;
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_GET_FET_CONTROL:
                if ((power_ic_get_reg_value(POWER_IC_REG_ATLAS_CHARGER_0, 10, (int *)&(fet_ctrl), 2)) != 0)
                {
                    ret_val = -EIO;
                }
                /* Only the sense value read needs to be sent back to the caller. */
                else if(put_user(fet_ctrl, (((int *)arg))) != 0)
                {
                    tracemsg(_k_d("error copying read bits to user space."));
                    ret_val = -EFAULT;
                }
                break;
                   
            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_FET_CONTROL:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_CHARGER_0, 10,
                                       arg, 2);
                break;
                
            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_VBUS_5K_PD:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_CHARGER_0, 19,
                                       (arg == 0 ? 0 : 1), 1);
                break;
         
            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_VBUS_70K_PD:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 6,
                                       (arg == 0 ? 0 : 1), 1);
                               
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_REVERSE_MODE:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_CHARGE_USB_1, 5,
                                   (arg == 0 ? 0 : 1), 1);
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_ID_PU:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 22,
                                       (arg == 0 ? 0 : 1), 1);
                break;            
         
            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_ID_PD:
                 power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 20,
                                       (arg == 0 ? 0 : 1), 1);
                 break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_ID_STEREO_PU:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_CHARGE_USB_1, 8,
                                       (arg == 0 ? 0 : 1), 1);
                break;  

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_CONN_MODE:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 14,
                                       arg, 3);
                break;  

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_DPLUS_150K_PU:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 5,
                                       (arg == 0 ? 0 : 1), 1);            
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_DPLUS_1_5K_PU:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 2,
                                       (arg == 0 ? 0 : 1), 1); 
                break;
  
            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_LOW_SPEED_MODE:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 0,
                                       (arg == 0 ? 0 : 1), 1);    
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_USB_SUSPEND:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_USB_0, 1,
                                       (arg == 0 ? 0 : 1), 1);    
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_TRANSCEIVER_PARAMS:
                /* Fetch the data passed from user space. */
                if(copy_from_user((void *)&trans_params, (void *)arg, sizeof(trans_params)) != 0)
                {
                    tracemsg(_k_d("error copying data from user space."));
                    ret_val = -EFAULT;
                }
                else
                {
                    /* Call local function */
                    emu_glue_set_transceiver_params(trans_params);
                }
                break;

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_ID_INT_MASK:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_INT_MASK_0, 19,
                                       arg, 1);    
                break;  

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_VBUS_INT_MASK:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_INT_MASK_0, 16,
                                       arg, 1);    
                break; 

            case POWER_IC_IOCTL_CMD_EMU_GLUE_SET_SE1_INT_MASK:
                power_ic_set_reg_value(POWER_IC_REG_ATLAS_INT_MASK_0, 21,
                                       arg, 1);    
                break;

            default: /* This shouldn't be able to happen, but just in case... */
                tracemsg(_k_d("=> 0x%X unsupported emu proc ioctl command"), (int) cmd);
                ret_val = -ENOTTY;
                break;
        }
    }
    else /* The driver doesn't support this request. */
    {
        tracemsg(_k_d("0x%X unsupported ioctl command"), (int) cmd);
        ret_val = -ENOTTY;
    }
        
    return ret_val;
}
コード例 #29
0
/*!
 * @brief Used to debounce the device type
 *
 * The debouncing of the accessory is done using the base accessory type
 * (self-powered versus phone-powered).  The purpose of the event handler is to
 * wait until the base accessory type has stabilized before continuing with
 * accessory identification.  This is accomplished by having the event handler
 * execute every 100 milliseconds until the base accessory type has not changed
 * for 300 milliseconds.
 * Once the debounce is complete, the event handler will perform the initial
 * accessory identification and transition to the appropriate next state.
 * 
 * @param polling_interval a return parameter that points to the "polling rate"
 *
 * @return next_state tells the state machine what the next EMU state is
 */
EMU_STATE_T debounce_dev_type_handler(int *polling_interval)
{
    EMU_ID_RESISTOR_T id_res;
    EMU_DEV_TYPE_T device_type;
    EMU_STATE_T next_state;
    
    /* Debounce the device type */
    if ((is_device_type_debounced(&device_type)) == FALSE)
    {
        /* Come back to this state after polling interval expires */
        *polling_interval = EMU_POLL_DFLT_DEB_DELAY;
        
        return EMU_STATE_CONNECTING__DEBOUNCE_DEV_TYPE;      
    }

    /* Finished debouncing, reset the counter */
    emu_debounce_counter = 0;
    
    /* Store the device type */
    emu_current_device_type = device_type;
    
    /* Now that the device type is debounced... */
    switch (device_type)
    {
        case EMU_DEV_TYPE_PPD:
            tracemsg(_k_d("EMU: debounce_dev_type_handler: EMU_DEV_TYPE_PPD"));
            
            /* Verify that ID res is 100k */
            if (get_id_res_value() != EMU_ID_RESISTOR_100K)
            {                
                /*if ID is not 100k, the accy is invalid */
                emu_current_device = MOTO_ACCY_TYPE_INVALID;
                next_state =  EMU_STATE_CONNECTED__INVALID;
                tracemsg(_k_d("EMU: debounce_dev_type_handler: ID != 100k"));
            }
            else
            {
                /* Go to the first PPD polling state */
                next_state = EMU_STATE_CONNECTING__PPD_VALIDATE;
            }
            break;
            
        case EMU_DEV_TYPE_SPD:
            tracemsg(_k_d("EMU: debounce_dev_type_handler: EMU_DEV_TYPE_SPD"));
            
            /* Get the resistance on ID */
            id_res = get_id_res_value();
            
            /* Is the device single ended one */
            if (get_bus_state(EMU_BUS_SIGNAL_SE1))
            {
                id_res += EMU_ID_RESISTOR_SE1;
            }

            emu_current_device = spd_id_translation_table[id_res].device;
            next_state = spd_id_translation_table[id_res].next_state;

            /* If we were previously in the unpowered SIHF state, and the
               device is still not behaving (looks like an unpowered sihf),
               set the device as invalid and transition to the connected state */
            if ((emu_prev_state == EMU_STATE_CONNECTING__UNPOWERED_SIHF) &&
                (next_state == EMU_STATE_CONNECTING__UNPOWERED_SIHF))
            {
                emu_current_device = MOTO_ACCY_TYPE_INVALID;
                next_state = EMU_STATE_CONNECTED__INVALID;
            }
            break;
            
        case EMU_DEV_TYPE_NOT_SUPPORTED:
            tracemsg(_k_d("EMU: debounce_dev_type_handler: EMU_DEV_TYPE_NOT_SUPPORTED"));
            
            emu_current_device = MOTO_ACCY_TYPE_NOT_SUPPORTED;
            next_state = EMU_STATE_CONNECTED__NOT_SUPPORTED;
            break;
            
        case EMU_DEV_TYPE_INVALID:
            tracemsg(_k_d("EMU: debounce_dev_type_handler: EMU_DEV_TYPE_INVALID"));
                
            emu_current_device = MOTO_ACCY_TYPE_INVALID;
            next_state = EMU_STATE_CONNECTED__INVALID;
            break;
            
        case EMU_DEV_TYPE_NONE:
            tracemsg(_k_d("EMU: debounce_dev_type_handler: EMU_DEV_TYPE_NONE"));
        default:
            emu_current_device = MOTO_ACCY_TYPE_NONE;
            next_state = EMU_STATE_DISCONNECTED;
            break;
    }

    tracemsg(_k_d("EMU: debounce_dev_type_handler: current_device = %d, next_state = %d"),
             emu_current_device, next_state);

    *polling_interval = EMU_POLL_CONTINUE;
    
    return next_state;
}
コード例 #30
0
/*!
 * @brief Connecting State: spd_delay_handler function
 *
 * The event handler for this state will only be called after the 5 millisecond
 * delay and is responsible for checking the state of the D- line.
 *
 * @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 spd_delay_handler(int *polling_interval)
{
    int vbus;
    EMU_STATE_T next_state = EMU_STATE_CONNECTED__POLL_SPD_REMOVAL;
        
    /* Verify that the device type didn't change while polling */
    if (get_device_type() != EMU_DEV_TYPE_SPD)
    {
        tracemsg(_k_d("EMU: spd_delay_handler:device type changed while polling!"));

        *polling_interval = EMU_POLL_CONTINUE;
        
        /* Something changed debounce the accy again */
        return EMU_STATE_CONNECTING__DEBOUNCE_DEV_TYPE;
    }
    
    /* If dminus is high then this charger is a SIHF */
    if (get_bus_state(EMU_BUS_SIGNAL_DMINUS))
    {
        if (emu_current_device == MOTO_ACCY_TYPE_CHARGER_FAST)
        {
            emu_current_device = MOTO_ACCY_TYPE_CARKIT_FAST;
        }
        else
        {
            emu_current_device = MOTO_ACCY_TYPE_CARKIT_MID;
        }
    }
    else
    {
        if (emu_current_device == MOTO_ACCY_TYPE_CHARGER_FAST)
        {
            /* Convert the Batt+ channel to get the VBUS voltage */
            if (power_ic_atod_single_channel(EMU_A2D_VBUS, &vbus) != 0)
            {
                vbus = 0;
            }
            
            if (vbus >= EMU_VBUS_5VOLTS)
            {
                /*current_device is already set correctly */
                /*current_device = MOTO_ACCY_TYPE_CHARGER_FAST;*/
            }
            else if (vbus >= EMU_VBUS_4_5VOLTS)
            {
                emu_current_device = MOTO_ACCY_TYPE_CHARGER_FAST_3G;
            }
            else /*if (vbus < VBUS_4_5VOLTS)*/
            {
                emu_current_device = MOTO_ACCY_TYPE_INVALID;
                next_state = EMU_STATE_CONNECTED__INVALID;
            }
        }
        /*else if (emu_current_device == MOTO_ACCY_TYPE_CHARGER_MID) */
        /* Nothing to do here for Mid rate chargers */
    }

    tracemsg(_k_d("EMU: current_device = %d"),
             emu_current_device);

    *polling_interval = EMU_POLL_CONTINUE;
    
    /* Go to the determined connected substate */
    return next_state;
}