コード例 #1
0
static ssize_t
reset_reason_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	int index;
#ifdef CONFIG_BCM_POWEROFF_CHARGING
	int reset_reason;

	reset_reason = board_sysconfig(SYSCFG_RESETREASON_SOFT_RESET, SYSCFG_INIT);
	switch (reset_reason) {
	case POWER_ON_RESET:
		index = 0;
		break;
	case SOFT_RESET:
		index = 1;
		break;
	case POWEROFF_CHARGING:
		index = 2;
		board_sysconfig(SYSCFG_RESETREASON_SOFT_RESET, SYSCFG_ENABLE);
		break;
	default:
		index = 3;
		break;
	}
	sprintf(buf, "%s\n", str_reset_reason[index]);
#else /* BCM_POWEROFF_CHARGING */
	index = 0; /* Return POWER_ON_RESET always */
#endif /* BCM_POWEROFF_CHARGING */
	return strlen(str_reset_reason[index]) + 1;
}
コード例 #2
0
// Switch class work to update state of headset
static void switch_work(struct work_struct *work)
{
    struct h2w_switch_data *data =
                container_of(to_delayed_work(work), struct h2w_switch_data, work);
	int headset_state;

        if (mic.headset_pd->check_hs_state) {
		enable_irq(mic.hsirq);
		mic.headset_pd->check_hs_state(&headset_state);

		/* Check headset state after the debounce time,
		 * if same exit, as there is no state change */
		if (headset_state == mic.headset_state)
			return;
		mic.headset_state = headset_state;
	}

        switch_set_state(&data->sdev, mic.headset_state);
	if(mic.headset_state){
		 if(mic.hsbst){
			mic.hsbst = 0;
			/* Turn on the Rx LDO on headset insertion, this 
			 * will only be applicable if headset detect is from GPIO
			 */
			if (mic.headset_pd->check_hs_state)
				writel(AUDIO_RX_LDO_ON(readl(io_p2v(REG_ANACR2))), 
						io_p2v(REG_ANACR2));
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_INIT);
		 	enable_irq(mic.hsbirq);
		 }
	} else {
		if(!mic.hsbst){
		 	disable_irq(mic.hsbirq);
			/* Turn off the Rx LDO on headset removal, this will only be
			 * applicable if headset detect is from GPIO
			 */
			if (mic.headset_pd->check_hs_state)
				// [email protected] 2012.05.02 begin
				// fix bug csp 522980. merge brcm patch
			{
				if (!((readl(io_p2v(REG_ANACR2))) & 0x4))
					writel(AUDIO_RX_LDO_OFF(readl(io_p2v(REG_ANACR2))), 
						io_p2v(REG_ANACR2));
      }
			  // [email protected] 2012.05.02 end
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);
			mic.hsbst = 1;
		}
	}
}
コード例 #3
0
static void getIMSI_work_func(struct work_struct *work)
{
	SIMLOCK_SIM_DATA_t* simdata = GetSIMData();
	
	if(simdata == NULL)
	{
		//printk("%s: IMSI NULL\n", __func__);
		FactoryMode = DISABLE;
	}
	else
	{
		//printk("%s: IMSI %s\n", __func__, simdata->imsi_string);
		FactoryMode = strncmp(simdata->imsi_string, "999999999999999", IMSI_DIGITS) == 0 ?  ENABLE : DISABLE;
	}
	
	printk("%s: Factorymode %d\n", __func__, FactoryMode);

	if(FactoryMode == ENABLE)
	{
		if(mic.headset_state)
		{
			if(mic.hsbst == ENABLE && mic.headset_state == HEADSET_4_POLE)
				board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
		}
	}
}
コード例 #4
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
/*------------------------------------------------------------------------------
Function name   : hs_isr
Description     : interrupt handler

Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_isr(int irq, void *dev_id)
{
	struct mic_t *p = &mic;
	int pre_data = -1;
	int loopcnt = 0;

	wake_lock_timeout(&p->det_wake_lock, WAKE_LOCK_TIME);
	p->pluging = ENABLE;
	sync_use_mic = ENABLE;

	printk("%s: Before state : %d \n", __func__, p->headset_state);

#if 0
	/* For remove pop-up noise.*/
	if(p->headset_state && (p->keypressing == NONE || p->keypressing == INIT))
	{		
		printk("%s: Remove popup noise\n", __func__);
		board_sysconfig(SYSCFG_HEADSET, SYSCFG_DISABLE);
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);
	}
#endif
	
	/* debounce headset jack.  don't try to determine the type of
	 * headset until the detect state is true for a while.
	 */
	while (1)
	{
		p->headset_pd->check_hs_state(&(p->headset_state));
		if (pre_data == p->headset_state)
			loopcnt++;
		else
			loopcnt = 0;

		pre_data = p->headset_state;

		if (loopcnt >= HEADSET_DETECT_REF_COUNT)
			break;
		
		msleep(30);
	}

	set_irq_type(p->headset_pd->hsirq, (p->headset_state) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
	determine_state_func();

	return IRQ_HANDLED;
}
コード例 #5
0
//*****************************************************************************
//
// Function Name: dsi_teon
// 
// Description:   Configure TE Input Pin & Route it to DSI Controller Input
//
//*****************************************************************************
static int dsi_teon ( dsic_panel_t *pPanel )
{
    Int32       res = 0;
    
	board_sysconfig(SYSCFG_LCD, SYSCFG_ENABLE);
	
    return ( res );
}
コード例 #6
0
ファイル: brcm_headset.c プロジェクト: manoranjan2050/Compact
static ssize_t hs_Store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	ssize_t ret = 0;
	const ptrdiff_t off = attr - hs_Attrs;

	switch (off)
	{
		case ATTR_THRESHOLD:
			ret += sscanf(buf, "%d\n%d\n%d\n%d\n%d\n%d\n%d\n", \
				(int*)(&KEY_3POLE_THRESHOLD), (int*)(&KEY1_THRESHOLD_L), (int*)(&KEY1_THRESHOLD_U),\
				(int*)(&KEY2_THRESHOLD_L), (int*)(&KEY2_THRESHOLD_U), (int*)(&KEY3_THRESHOLD_L),\
				(int*)(&KEY3_THRESHOLD_U));

			queue_work(mic.headset_workqueue, &Write_work);
			break;
		case ATTR_TESTON:
			{
			int teston = 0;
			ret += sscanf(buf, "%d\n", &teston);
			printk("%s: teston %d\n", __func__, teston);
			TestMode = (teston == 1)? ENABLE : DISABLE;

			if(TestMode == ENABLE)
			{
				if(mic.headset_state == HEADSET_4_POLE)
					board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
			}
			else
			{
				if(mic.headset_state == HEADSET_4_POLE)
					board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);
			}
			
			}
			break;			
		default :			
			break;
	}

	return ret;
}
コード例 #7
0
static void type_work_func(struct work_struct *work)
{
#ifdef REG_DEBUG
	unsigned long val_anacr2, val_cmc, val_auxen;
#endif

	int adc = auxadc_access(2);

	if(adc>=KEY_3POLE_THRESHOLD)
	{
		if(FactoryMode == DISABLE)
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);

		if (mic.headset_pd->check_hs_state)
			board_sysconfig(SYSCFG_HEADSET, SYSCFG_ENABLE);

		mic.headset_state = HEADSET_4_POLE;
		printk("%s: 4-pole inserted : ear_adc=%d\n", __func__, adc);
	}
	else
	{
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);

		mic.headset_state = HEADSET_3_POLE;
		printk("%s: 3-pole inserted : ear_adc=%d\n", __func__, adc);
	}

	switch_set_state(&(mic.switch_data.sdev), mic.headset_state);

	if(FactoryMode == DISABLE)
	sync_use_mic = DISABLE;

#ifdef REG_DEBUG
	val_anacr2 = readl(io_p2v(REG_ANACR2));
	val_cmc = readl(io_p2v(REG_AUXMIC_CMC));
	val_auxen = readl(io_p2v(REG_AUXMIC_AUXEN));
	printk("%s: REG_ANACR2=%x, REG_AUXMIC_CMC=%x, REG_AUXMIC_AUXEN=%x\n", __func__, val_anacr2, val_cmc, val_auxen);
#endif

}
コード例 #8
0
// Switch class work to update state of headset
static void switch_work(struct work_struct *work)
{
#ifdef REG_DEBUG
	unsigned long val_anacr2, val_cmc, val_auxen;
	val_anacr2 = readl(io_p2v(REG_ANACR2));
	val_cmc = readl(io_p2v(REG_AUXMIC_CMC));
	val_auxen = readl(io_p2v(REG_AUXMIC_AUXEN));
	printk("%s: REG_ANACR2=%x, REG_AUXMIC_CMC=%x, REG_AUXMIC_AUXEN=%x\n", __func__, val_anacr2, val_cmc, val_auxen);
#endif

	if(mic.headset_state)
	{
		if(mic.hsbst == DISABLE)
		{
			mic.hsbst = ENABLE;
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);			
			schedule_delayed_work(&(mic.type_work), TYPE_DETECT_REF_TIME);
		}
	}
	else
	{
		if(mic.hsbst == ENABLE)
		{
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);

			if (mic.headset_pd->check_hs_state)
				board_sysconfig(SYSCFG_HEADSET, SYSCFG_DISABLE);

			mic.hsbst = DISABLE;
			sync_use_mic = DISABLE;
			switch_set_state(&(mic.switch_data.sdev), mic.headset_state);

			printk("%s: plugged out\n", __func__);
		}
	}
}
コード例 #9
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
static void type_work_func(struct work_struct *work)
{
	int adc = 0;

	if(mic.headset_state)
	{
		adc = auxadc_access(2);
		if(adc >= KEY_3POLE_THRESHOLD)
		{
			if(FactoryMode == DISABLE)
				board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);

			board_sysconfig(SYSCFG_HEADSET, SYSCFG_ENABLE);
			
			mic.headset_state = HEADSET_4_POLE;
			mic.hsbtime = ktime_get();
			ENABLE_IRQ_MICON;
			printk("%s: 4-pole inserted : ear_adc=%d\n", __func__, adc);
		}
		else
		{
			if(FactoryMode == DISABLE)
				board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);
			
			mic.headset_state = HEADSET_3_POLE;
			printk("%s: 3-pole inserted : ear_adc=%d\n", __func__, adc);
		}

		mic.pluging = DISABLE;

		if(FactoryMode == DISABLE)
		sync_use_mic = DISABLE;

		switch_set_state(&mic.sdev, mic.headset_state);
	}
}
コード例 #10
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
static void determine_state_func(void)
{
	if(mic.headset_state)
	{
		board_sysconfig(SYSCFG_HEADSET, SYSCFG_ENABLE);
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);

		cancel_delayed_work(&(mic.type_work));
		queue_delayed_work(mic.headset_workqueue, &(mic.type_work), TYPE_DETECT_REF_TIME);
	}
	else
	{
		board_sysconfig(SYSCFG_HEADSET, SYSCFG_DISABLE);
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);
		
		DISABLE_IRQ_MICON;

		mic.pluging = DISABLE;
		mic.keypressing = INIT;
		sync_use_mic = DISABLE;		
		switch_set_state(&mic.sdev, mic.headset_state);
		printk("%s: plugged out\n", __func__);
	}
}
コード例 #11
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
/*------------------------------------------------------------------------------
Function name   : hs_buttonisr
Description     : interrupt handler

Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_buttonisr(int irq, void *dev_id)
{
	struct mic_t *p = &mic;
	int val = 0;
	ktime_t temptime;
	
	if(mic.keypressing == INIT)
	{
		temptime = ktime_get();
		temptime = ktime_sub(temptime, mic.hsbtime);
		if(temptime.tv.sec >= 1 || temptime.tv.nsec >= KEY_INTERRUPT_REF_TIME)
			mic.keypressing = NONE;
		else
		{
		 	printk("%s: Initializing HSB ISR\n", __func__ );
			return IRQ_NONE;
		}
	}	

	if(p->pluging ==  ENABLE || p->keypressing != NONE)
	{
		printk("%s: Headset pluging OR keypressing\n", __func__ );
		return IRQ_NONE;
	}

	val = readl(io_p2v(REG_ANACR12));
	if(val < KEY_PRESS_THRESHOLD)
	{
		printk("%s: False button interrupt\n", __func__ );
		return IRQ_NONE;	
	}
	
	if (p->headset_state == HEADSET_4_POLE)
	{	
		p->hsbtime = ktime_get();
		
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
		
		memset(mic.key_count, 0, sizeof(mic.key_count));
		p->keypressing = PRESS;
		sync_use_mic = ENABLE;

		cancel_delayed_work(&(mic.input_work));
		queue_delayed_work(mic.headset_workqueue, &(p->input_work), KEY_BEFORE_PRESS_REF_TIME);
	}

	 return IRQ_HANDLED;
}
コード例 #12
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
/* 	1 : SIM_DUAL_FIRST,
	2 : SIM_DUAL_SECOND */
static void getIMSI_work_func(struct work_struct *work)
{
	SIMLOCK_SIM_DATA_t* simdata = GetSIMData();
	
	if(simdata == NULL)
	{
		FactoryMode = DISABLE;
	}
	else
	{
		FactoryMode = strncmp(simdata->imsi_string, TEST_SIM_IMSI, IMSI_DIGITS) == 0 ?  ENABLE : DISABLE;
	}
	
	if(FactoryMode == ENABLE)
	{
		if(mic.headset_state == HEADSET_4_POLE)
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
	}
}
コード例 #13
0
ファイル: csl_dma.c プロジェクト: Bazztord/Merruk-Technology
/* ****************************************************************************** */
void csl_dma_start_transfer(DMA_CHANNEL chanID, DMADRV_LLI_T pLLI)
{
	dmac_t *pdma = (dmac_t *) & dmac;
	UInt32 assocChan = ASSOC_CHAN_NONE;
	ASSOC_CHAN_t *pAssocChan = (ASSOC_CHAN_t *) pLLI;

#if (defined (_HERA_) || defined (_RHEA_) || defined (_SAMOA_))
	chal_dmac_ucode_t ucode;
	ucode.alloc = dma_ucode_alloc;
	ucode.coherency = dma_ucode_coherency;
	ucode.free = dma_ucode_free;
#endif

	if (!pdma->initialized) {
		/* dprintf(1, "csl_dma: dmac has not been initialized\n"); */
		return;
	}
		/* Set AHB clock request generated on per-channel basis
		 * This is to ensure Athena enters deep sleep/pedestal mode
		 */
		chanArray[chanID].busy = TRUE;
		board_sysconfig(SYSCFG_CSL_DMA, SYSCFG_DISABLE);
#if (defined (_HERA_) || defined (_RHEA_) || defined (_SAMOA_))
	chal_dma_prepare_transfer(pdma->handle, chanID, &ucode);
	chal_dmux_protect(pdma->dmuxHandle);
	chal_dma_start_transfer(pdma->handle, chanID, &ucode);
	chal_dmux_unprotect(pdma->dmuxHandle);
#else
	if (pLLI != NULL) {
		assocChan = pAssocChan->assocChan;
	} else {
		assocChan = ASSOC_CHAN_NONE;
	}
	chal_dma_start_transfer(pdma->handle, chanID, assocChan);
#endif

	return;
}
コード例 #14
0
static int __init hs_probe(struct platform_device *pdev)
{
	int result = 0;
	mic.hsmajor = 0;
	mic.headset_state = 0;
	mic.hsbtime.tv.sec = 0;
	mic.hsbtime.tv.nsec = 0;
	mic.headset_pd = NULL;
	mic.check_count = 0;

#ifdef CONFIG_SWITCH
	result = hs_switchinit(&mic);
	if (result < 0)
		return result;
#endif

	result = hs_inputdev(&mic);
	if (result < 0)
		goto err;

	result = register_chrdev(mic.hsmajor, "BrcmHeadset", &hs_fops);
	if(result < 0)
		goto err1;
	else if(result > 0 && (mic.hsmajor == 0))    /* this is for dynamic major */
		mic.hsmajor = result;

	wake_lock_init(&mic.det_wake_lock, WAKE_LOCK_SUSPEND, "sec_jack_det");
	INIT_DELAYED_WORK(&(mic.imsi_work), getIMSI_work_func);

	/* check if platform data is defined for a particular board variant */
	if (pdev->dev.platform_data)
	{
		mic.headset_pd = pdev->dev.platform_data;

		KEY_PRESS_THRESHOLD = mic.headset_pd->key_press_threshold;
		KEY_3POLE_THRESHOLD = mic.headset_pd->key_3pole_threshold;
		KEY1_THRESHOLD_L = mic.headset_pd->key1_threshold_l;
		KEY1_THRESHOLD_U = mic.headset_pd->key1_threshold_u;
		KEY2_THRESHOLD_L = mic.headset_pd->key2_threshold_l;
		KEY2_THRESHOLD_U = mic.headset_pd->key2_threshold_u;
		KEY3_THRESHOLD_L = mic.headset_pd->key3_threshold_l;
		KEY3_THRESHOLD_U = mic.headset_pd->key3_threshold_u;

		if (mic.headset_pd->hsgpio == NULL)
			mic.hsirq = mic.headset_pd->hsirq;
		else
		{
			setup_timer(&mic.timer, gpio_jack_timer, (unsigned long)&mic); // timer register. 

			if (gpio_request(mic.headset_pd->hsgpio, "headset detect") < 0)
			{
				printk("%s: Could not reserve headset signal GPIO!\n", __func__);
				goto err2;
			}
			gpio_direction_input(mic.headset_pd->hsgpio);
			bcm_gpio_set_db_val(mic.headset_pd->hsgpio, 0x7);
			mic.hsirq = gpio_to_irq(mic.headset_pd->hsgpio);
		}
		mic.hsbirq = mic.headset_pd->hsbirq;
	}
	else
	{
		mic.hsirq = platform_get_irq(pdev, 0);
		mic.hsbirq = platform_get_irq(pdev, 1);
	}

	printk("%s: HS irq %d\n", __func__, mic.hsirq);
	printk("%s: HSB irq %d\n", __func__, mic.hsbirq);
	result = request_irq(mic.hsbirq, hs_buttonisr,  IRQF_NO_SUSPEND, "BrcmHeadsetButton",  (void *) NULL);
	mic.hsbst = DISABLE;

	if(result < 0)
		goto err2;

	result = request_irq(mic.hsirq, hs_isr,(IRQF_DISABLED | IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND), "BrcmHeadset",  &mic);
	if(result < 0)
	{
		free_irq(mic.hsbirq, &mic);
		goto err2;
	}

	printk("%s: BrcmHeadset: module inserted >>>> . Major number is = %d\n", __func__, mic.hsmajor);

	/* Set the ANACR2 bit for mic power down */
	board_sysconfig(SYSCFG_AUXMIC, SYSCFG_INIT);
	board_sysconfig(SYSCFG_HEADSET, SYSCFG_INIT);

	/*Fix the audio path is wrong when headset already plugged in the device  then boot device case.*/
	if (mic.headset_pd->hsgpio != NULL)
	{
		mic.headset_pd->check_hs_state(&mic.headset_state);
		printk("%s: headset_state:%d\n", __func__, mic.headset_state); 
		set_irq_type(mic.hsirq, (mic.headset_state) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
		schedule_work(&(mic.switch_data.work));
		schedule_delayed_work(&(mic.imsi_work), GET_IMSI_REF_TIME);
	}

	return 0;

err2:   unregister_chrdev(mic.hsmajor,"BrcmHeadset");
	if(mic.headset_pd->hsgpio)
		del_timer_sync(&mic.timer);
err1:   hs_unreginputdev(&mic);
err:    hs_unregsysfs(&mic);
	return result;
}
コード例 #15
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
static void input_work_func(struct work_struct *work)
{
	int adc_value = -1;
	int val = 0;
	ktime_t temptime;

	adc_value = auxadc_access(2);
	val = readl(io_p2v(REG_ANACR12));
//	printk("%s: REG_ANACR2=%d, REG_ANACR12=%d\n", __func__,adc_value , val);

	if(val >= KEY_PRESS_THRESHOLD && adc_value >= KEY1_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U)
	{
		temptime = ktime_get();
		temptime = ktime_sub(temptime, mic.hsbtime);

		if(temptime.tv.nsec < VALID_RELEASE_REF_TIME && mic.keypressing == PRESS)
		{
			if ( adc_value >= KEY1_THRESHOLD_L && adc_value < KEY1_THRESHOLD_U )
			{
				mic.key_count[0]++;
				printk ("KEY_BCM_HEADSET_BUTTON \n");
			}
			else if ( adc_value >= KEY2_THRESHOLD_L && adc_value < KEY2_THRESHOLD_U ) 
			{
				mic.key_count[1]++;
				printk ("KEY_VOLUMEUP \n");
			}
			else if ( adc_value >= KEY3_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U ) 
			{
				mic.key_count[2]++;
				printk ("KEY_VOLUMEDOWN \n");
			}
		}
		else
		{
			if(mic.keypressing == PRESS && (mic.key_count[0] + mic.key_count[1] + mic.key_count[2]))
			{
				input_report_key(mic.headset_button_idev, Return_valid_key(mic.key_count), PRESS);
				input_sync(mic.headset_button_idev);

				set_button(1); 
				mic.keypressing = RELEASE;
			}
		}

		cancel_delayed_work(&(mic.input_work));
		queue_delayed_work(mic.headset_workqueue, &(mic.input_work), KEY_PRESS_REF_TIME);
	}
	else
	{
		if(mic.keypressing == RELEASE && (mic.key_count[0] + mic.key_count[1] + mic.key_count[2]))
		{			
			printk ("%s: RELEASE key_count [%d, %d, %d] \n", __func__,  mic.key_count[0], mic.key_count[1], mic.key_count[2]);
			input_report_key(mic.headset_button_idev, Return_valid_key(mic.key_count), RELEASE);
			input_sync(mic.headset_button_idev);
		}
		else
		{
			printk("%s: NO PRESS\n",  __func__);
		}

		if(FactoryMode == DISABLE)
		{
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);
			sync_use_mic = DISABLE;		
		}
		
		set_button(0); 
		mic.keypressing = NONE;
	}
}
コード例 #16
0
ファイル: brcm_headset.c プロジェクト: manoranjan2050/Compact
static void input_work_func(struct work_struct *work)
{
	int adc_value = -1;
	int val = 0;
	ktime_t temptime;

	adc_value = auxadc_access(2);
	val = readl(io_p2v(REG_ANACR12));
//	printk("%s: REG_ANACR2=%d, REG_ANACR12=%d\n", __func__,adc_value , val);

#ifdef USE_SERVICEMODE
	if(val >= KEY_PRESS_THRESHOLD && adc_value >= Min_threshold && adc_value < Max_threshold)
	{
#else
	if(val >= KEY_PRESS_THRESHOLD && adc_value >= KEY1_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U)
	{
#endif
		temptime = ktime_get();
		temptime = ktime_sub(temptime, mic.hsbtime);

		if(temptime.tv.nsec < VALID_RELEASE_REF_TIME && mic.keypressing == PRESS)
		{
			if ( adc_value >= KEY1_THRESHOLD_L && adc_value < KEY1_THRESHOLD_U )
			{
				mic.key_count[0]++;
				printk ("KEY_BCM_HEADSET_BUTTON \n");
			}
			else if ( adc_value >= KEY2_THRESHOLD_L && adc_value < KEY2_THRESHOLD_U ) 
			{
				mic.key_count[1]++;
				printk ("KEY_VOLUMEUP \n");
			}
			else if ( adc_value >= KEY3_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U ) 
			{
				mic.key_count[2]++;
				printk ("KEY_VOLUMEDOWN \n");
			}
		}
		else
		{
			if(mic.keypressing == PRESS && (mic.key_count[0] + mic.key_count[1] + mic.key_count[2]))
			{
				input_report_key(mic.headset_button_idev, Return_valid_key(mic.key_count), PRESS);
				input_sync(mic.headset_button_idev);

				set_button(1); 
				mic.keypressing = RELEASE;
			}
		}

		cancel_delayed_work(&(mic.input_work));
		queue_delayed_work(mic.headset_workqueue, &(mic.input_work), KEY_PRESS_REF_TIME);
	}
	else
	{
		if(mic.keypressing == RELEASE && (mic.key_count[0] + mic.key_count[1] + mic.key_count[2]))
		{			
			printk ("%s: RELEASE key_count [%d, %d, %d] \n", __func__,  mic.key_count[0], mic.key_count[1], mic.key_count[2]);
			input_report_key(mic.headset_button_idev, Return_valid_key(mic.key_count), RELEASE);
			input_sync(mic.headset_button_idev);
		}
		else
		{
			printk("%s: NO PRESS\n",  __func__);
		}

		if(FactoryMode == DISABLE)
		{
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);
			sync_use_mic = DISABLE;		
		}
		
		set_button(0); 
		mic.keypressing = NONE;
	}
}

/*------------------------------------------------------------------------------
Function name   : hs_buttonisr
Description     : interrupt handler

Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_buttonisr(int irq, void *dev_id)
{
	struct mic_t *p = &mic;
	int val = 0;
	ktime_t temptime;
	
#ifdef USE_SERVICEMODE
	if(TestMode == ENABLE)
	{
		if(p->headset_state == HEADSET_4_POLE)
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
		
		return IRQ_NONE;
	}
#endif
	
	if(mic.keypressing == INIT)
	{
		temptime = ktime_get();
		temptime = ktime_sub(temptime, mic.hsbtime);
		if(temptime.tv.sec >= 1 || temptime.tv.nsec >= KEY_INTERRUPT_REF_TIME)
			mic.keypressing = NONE;
		else
		{
		 	printk("%s: Initializing HSB ISR\n", __func__ );
			return IRQ_NONE;
		}
	}	

	if(p->pluging ==  ENABLE || p->keypressing != NONE)
	{
		printk("%s: Headset pluging OR keypressing\n", __func__ );
		return IRQ_NONE;
	}

	val = readl(io_p2v(REG_ANACR12));
	if(val < KEY_PRESS_THRESHOLD)
	{
		printk("%s: False button interrupt\n", __func__ );
		return IRQ_NONE;	
	}
	
	if (p->headset_state == HEADSET_4_POLE)
	{	
		p->hsbtime = ktime_get();
		
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
		
		memset(mic.key_count, 0, sizeof(mic.key_count));
		p->keypressing = PRESS;
		sync_use_mic = ENABLE;

		cancel_delayed_work(&(mic.input_work));
		queue_delayed_work(mic.headset_workqueue, &(p->input_work), KEY_BEFORE_PRESS_REF_TIME);
	}

	 return IRQ_HANDLED;
}

/* 	1 : SIM_DUAL_FIRST,
	2 : SIM_DUAL_SECOND */
static void getIMSI_work_func(struct work_struct *work)
{
	SIMLOCK_SIM_DATA_t* simdata = NULL; 
	int first = DISABLE;
	int second = DISABLE;

	simdata = GetSIMData(SIM_DUAL_FIRST);
	first = ((simdata == NULL) || (strncmp(simdata->imsi_string, TEST_SIM_IMSI, IMSI_DIGITS) != 0)) ?  DISABLE : ENABLE;
	simdata = GetSIMData(SIM_DUAL_SECOND);
	second = ((simdata == NULL) || (strncmp(simdata->imsi_string, TEST_SIM_IMSI, IMSI_DIGITS) != 0)) ?  DISABLE : ENABLE;

	FactoryMode = (first == ENABLE || second == ENABLE) ? ENABLE : DISABLE;
	printk("%s: Factorymode %d\n", __func__, FactoryMode);

	if(FactoryMode == ENABLE)
	{
		if(mic.headset_state == HEADSET_4_POLE)
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);
	}
}
コード例 #17
0
static int __init hs_probe(struct platform_device *pdev)
{
    int result;
    mic.hsmajor = 0;
    mic.headset_state = 0;
    mic.hsbtime.tv.sec = 0;
    mic.hsbtime.tv.nsec = 0;
    mic.headset_pd = NULL;
#ifdef CONFIG_SWITCH
    result = hs_switchinit(&mic);
    if (result < 0) {
        return result;
    }
#endif
    result = hs_inputdev(&mic);
    if (result < 0) {
        goto err;
    }
    result = register_chrdev(mic.hsmajor, "BrcmHeadset", &hs_fops);
    if(result < 0)
    {
	goto err1;
    }
    else if(result > 0 && (mic.hsmajor == 0))    /* this is for dynamic major */
    {
        mic.hsmajor = result;
    }

    /* check if platform data is defined for a particular board variant */
    if (pdev->dev.platform_data)
    {
         mic.headset_pd = pdev->dev.platform_data;
         if (mic.headset_pd->hsgpio == NULL)
         {
             mic.hsirq = mic.headset_pd->hsirq;
         }
         else
         {
		bcm_gpio_set_db_val(mic.headset_pd->hsgpio, 0x7);
             if (gpio_request(mic.headset_pd->hsgpio, "headset detect") < 0)
		       {
	              pr_info("Could not reserve headset signal GPIO!\n");
			       goto err2;
		       }
            gpio_direction_input(mic.headset_pd->hsgpio);
            mic.hsirq = gpio_to_irq(mic.headset_pd->hsgpio);
         }
       mic.hsbirq = mic.headset_pd->hsbirq;
    }
    else
    {
     	mic.hsirq = platform_get_irq(pdev, 0);
     	mic.hsbirq = platform_get_irq(pdev, 1);
    }
    pr_info("HS irq %d\n",mic.hsirq);
    pr_info("HSB irq %d\n",mic.hsbirq);
#if defined(CONFIG_HAS_WAKELOCK)
    wake_lock_init(&headsetbutton_wake_lock, WAKE_LOCK_SUSPEND, "BrcmHeadsetButton");
#endif
    result = request_irq(mic.hsbirq, hs_buttonisr, IRQF_NO_SUSPEND, "BrcmHeadsetButton",  (void *) NULL);
    mic.hsbst = 1; /* Disabled */
    disable_irq(mic.hsbirq);
    if(result < 0)
    {
	goto err2;
    }
    result = request_irq(mic.hsirq, hs_isr,(IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND), "BrcmHeadset",  &mic);
    if(result < 0)
    {
	free_irq(mic.hsbirq, &mic);
	goto err2;
    }

    /* Check if the thresholds have been set for a particular board */
    if (!mic.headset_pd->keypress_threshold_lp)
        mic.headset_pd->keypress_threshold_lp = KEYPRESS_THRESHOLD;

    if (!mic.headset_pd->keypress_threshold_fp)
        mic.headset_pd->keypress_threshold_fp = KEYPRESS_THRESHOLD;

    /* Set the ANACR2 bit for mic power down */
    board_sysconfig(SYSCFG_HEADSET, SYSCFG_INIT);

    board_sysconfig(SYSCFG_AUXMIC, SYSCFG_INIT);
    
    if (mic.headset_pd->check_hs_state)
	writel(AUDIO_RX_LDO_OFF(readl(io_p2v(REG_ANACR2))), io_p2v(REG_ANACR2));

    /*Fix the audio path is wrong when headset already plugged in the device  then boot device case.*/
    hs_isr(mic.hsirq,&mic);
    return 0;
err2:   unregister_chrdev(mic.hsmajor,"BrcmHeadset");
err1:   hs_unreginputdev(&mic);
	input_free_device(&mic.headset_button_idev);
err:    hs_unregsysfs(&mic);
	return result;
}
コード例 #18
0
ファイル: csl_dma.c プロジェクト: Bazztord/Merruk-Technology
/* ****************************************************************************** */
void csl_dma_process_callback(DMA_Interrupt_t * intStatus)
{
	UInt32 channel, mask, chnl_count;
	DMA_Interrupt_t localIntStatus;
	UInt32 flags;

	DEFINE_SPINLOCK(lock);	
	spin_lock_irqsave(&lock, flags);
	localIntStatus.errInt = intStatus->errInt;
	localIntStatus.tcInt  = intStatus->tcInt;
	intStatus->errInt = 0;
	intStatus->tcInt = 0;
	spin_unlock_irqrestore(&lock, flags);

	/* dprintf(1, "csl_dma: csl_dma_process_callback\n"); */

	for (channel = 0; channel < TOTAL_DMA_CHANNELS; channel++) {
		mask = (0x1 << channel);
		if (chanArray[channel].bUsed == FALSE)
			continue;

#if (defined (_HERA_) || defined (_RHEA_) || defined (_SAMOA_))
		if (chanArray[channel].bUsed
		    && chanArray[channel].chanInfo.xferCompleteCb) {
			chanArray[channel].chanInfo.
			    xferCompleteCb((DMADRV_CALLBACK_STATUS_t)
					   DMADRV_CALLBACK_OK);
		}
#else
		
		if (localIntStatus.errInt & mask) {
			/* dprintf(1, "Eirlys errInt, channel: %d, %d\n", channel, TIMER_GetValue()); */
			if (chanArray[channel].bUsed
			    && chanArray[channel].chanInfo.xferCompleteCb) {
				chanArray[channel].chanInfo.
				    xferCompleteCb((DMADRV_CALLBACK_STATUS_t)
						   DMADRV_CALLBACK_FAIL);
				spin_lock_irqsave(&lock, flags);
				if (chanArray[channel].chanInfo.freeChan) {
					csl_dma_release_channel((DMA_CHANNEL)
								channel);
				}
				spin_unlock_irqrestore(&lock, flags);
			}
		} else if (localIntStatus.tcInt & mask) {
			if (chanArray[channel].bUsed
			    && chanArray[channel].chanInfo.xferCompleteCb) {
				/* dprintf(1, "Eirlys tcInt, %d, %d, 0x%x\n", channel, */
				/*        TIMER_GetValue(), chanArray[channel].chanInfo.xferCompleteCb); */

				chanArray[channel].chanInfo.
				    xferCompleteCb((DMADRV_CALLBACK_STATUS_t)
						   DMADRV_CALLBACK_OK);
				spin_lock_irqsave(&lock, flags);
					chanArray[channel].busy = FALSE;
				if (chanArray[channel].chanInfo.freeChan) {
					csl_dma_release_channel((DMA_CHANNEL)
								channel);
				}
				spin_unlock_irqrestore(&lock, flags);
			}
		}
#endif
	}
		for (chnl_count = 0; chnl_count < TOTAL_DMA_CHANNELS;
		     chnl_count++) {
			if (chanArray[chnl_count].busy == TRUE) {
				return;
			}
		}
		/* Set AHB clock request generated on per-channel basis
		 * This is to ensure Athena enters deep sleep/pedestal mode*/
		board_sysconfig(SYSCFG_CSL_DMA, SYSCFG_ENABLE);
	return;
}
コード例 #19
0
syscfg_reset_reason_t get_ap_boot_mode(void)
{
	return board_sysconfig(SYSCFG_RESETREASON_AP_ONLY_BOOT,
			SYSCFG_INIT);
}
コード例 #20
0
/*
	Callback called before the device reboots.
	If the reboot cause is a recovery, this function is going
	to write the strings "boot-recovery" and "recovery" into the
	Bootloader Control Block (BCB) so the Android Bootloader can
	launch the recovery image instead of the boot image.
*/
static int
reboot_notifier_callback(
struct notifier_block *nb, unsigned long val, void *v)
{
	struct raw_hd_struct *mmc_hd = NULL;
	struct bootloader_message *bcb;
	char *flashblock = NULL;

	if (mmc_misc_hd == NULL)
		goto clean_up;
	else
		mmc_hd = mmc_misc_hd;

	if (v == NULL) {
		board_sysconfig(SYSCFG_RESETREASON_SOFT_RESET, SYSCFG_DISABLE);
		goto clean_up;
	}

	if (!strncmp(v, "recovery", 8))	{
		int i = 0;
		dev_t devid;
		struct block_device *bdev;
		struct bio bio;
		struct bio_vec bio_vec;
		struct completion complete;
		struct page *page;

		/* Allocate a buffer to hold a block from 'misc' */
		flashblock = kmalloc(mmc_hd->nr_sects * 512, GFP_KERNEL);

		memset(flashblock, 0, mmc_hd->nr_sects * 512);

		/* If the allocation fails, return */
		if (flashblock == NULL)
			goto clean_up;

		/* read the BCB from the misc partition */
		/* read the entire block as we'll have to
		   rewrite it hence we need to erase */
		devid = MKDEV(mmc_hd->major, mmc_hd->first_minor + mmc_hd->partno);
		bdev = open_by_devnum(devid, FMODE_READ);
		if (IS_ERR(bdev)) {
			printk(KERN_ERR "misc: open device failed with %ld\n",
				PTR_ERR(bdev));
			goto clean_up;
		}
		page = virt_to_page(bounce);

		while (i < mmc_hd->nr_sects) {
			bio_init(&bio);
			bio.bi_io_vec = &bio_vec;
			bio_vec.bv_page = page;
			bio_vec.bv_offset = 0;
			bio.bi_vcnt = 1;
			bio.bi_idx = 0;
			bio.bi_bdev = bdev;
			bio.bi_sector = i;
			if (mmc_hd->nr_sects - i >= 8) {
				bio_vec.bv_len = PAGE_SIZE;
				bio.bi_size = PAGE_SIZE;
				i += 8;
			} else {
				bio_vec.bv_len = (mmc_hd->nr_sects - i) * 512;
				bio.bi_size = (mmc_hd->nr_sects - i) * 512;
				i = mmc_hd->nr_sects;
			}
			init_completion(&complete);
			bio.bi_private = &complete;
			bio.bi_end_io = mmc_bio_complete;
			submit_bio(READ, &bio);
			wait_for_completion(&complete);

			/* Copy the read buffer */
			memcpy(flashblock + (i * 512), page, bio.bi_size);
		}

		blkdev_put(bdev, FMODE_READ);
		printk(KERN_ERR "misc: Bound to mmc block device '(%d:%d)'\n",
			mmc_hd->major, mmc_hd->first_minor + mmc_hd->partno);

		/* BCB is stored at 0-bytes */
		bcb = (struct bootloader_message *)&flashblock[0];

		/* set bcb.command to "boot-recovery" */
		strcpy(bcb->command, "boot-recovery");

		/* clean bcb.status */
		memset(bcb->status, 0, sizeof(bcb->status));

		/* set bcb.recovery to "recovery" */
		strcpy(bcb->recovery, "recovery");

		/* Write the block back to 'misc'
		   First, erase it */
		devid = MKDEV(mmc_hd->major, mmc_hd->first_minor +
			mmc_hd->partno);
		bdev = open_by_devnum(devid, FMODE_WRITE);
		if (IS_ERR(bdev)) {
			printk(KERN_ERR "misc: open device failed with %ld\n",
				PTR_ERR(bdev));
			goto clean_up;
		}
		page = virt_to_page(bounce);
		i = 0;

		while (i < mmc_hd->nr_sects) {
			bio_init(&bio);
			bio.bi_io_vec = &bio_vec;
			bio_vec.bv_page = page;
			bio_vec.bv_offset = 0;
			bio.bi_vcnt = 1;
			bio.bi_idx = 0;
			bio.bi_bdev = bdev;
			bio.bi_sector = i;
			if (mmc_hd->nr_sects - i >= 8) {
				bio_vec.bv_len = PAGE_SIZE;
				bio.bi_size = PAGE_SIZE;
				i += 8;
			} else {
				bio_vec.bv_len = (mmc_hd->nr_sects - i) * 512;
				bio.bi_size = (mmc_hd->nr_sects - i) * 512;
				i = mmc_hd->nr_sects;
			}
			init_completion(&complete);
			bio.bi_private = &complete;
			bio.bi_end_io = mmc_bio_complete;
			submit_bio(WRITE, &bio);
			wait_for_completion(&complete);
		}
		blkdev_put(bdev, FMODE_WRITE);

		/* Then write the block back */
		devid = MKDEV(mmc_hd->major, mmc_hd->first_minor +
			mmc_hd->partno);
		bdev = open_by_devnum(devid, FMODE_WRITE);
		if (IS_ERR(bdev)) {
			printk(KERN_ERR "misc: open device failed with %ld\n",
				PTR_ERR(bdev));
			goto clean_up;
		}
		page = virt_to_page(bounce);
		i = 0;

		while (i < mmc_hd->nr_sects) {
			bio_init(&bio);
			bio.bi_io_vec = &bio_vec;
			bio_vec.bv_page = page;
			bio_vec.bv_offset = 0;
			bio.bi_vcnt = 1;
			bio.bi_idx = 0;
			bio.bi_bdev = bdev;
			bio.bi_sector = i;
			if (mmc_hd->nr_sects - i >= 8) {
				/* Copy the BCB block to buffer */
				memcpy(bounce, flashblock + (i * 512), PAGE_SIZE);

				bio_vec.bv_len = PAGE_SIZE;
				bio.bi_size = PAGE_SIZE;
				i += 8;
			} else {
				/* Copy the BCB block to buffer */
				memcpy(bounce, flashblock + (i * 512),
					(mmc_hd->nr_sects - i) * 512);

				bio_vec.bv_len = (mmc_hd->nr_sects - i) * 512;
				bio.bi_size = (mmc_hd->nr_sects - i) * 512;
				i = mmc_hd->nr_sects;
			}
			init_completion(&complete);
			bio.bi_private = &complete;
			bio.bi_end_io = mmc_bio_complete;
			submit_bio(WRITE, &bio);
			wait_for_completion(&complete);
		}
		blkdev_put(bdev, FMODE_WRITE);
	}

	if (!strncmp(v, "ap_only", 7)) {
		board_sysconfig(SYSCFG_RESETREASON_AP_ONLY_BOOT, SYSCFG_DISABLE);
	}

clean_up:

	if (flashblock != NULL)
		kfree(flashblock);

	return NOTIFY_DONE;
}
コード例 #21
0
/*------------------------------------------------------------------------------
Function name   : hs_buttonisr
Description     : interrupt handler

Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_buttonisr(int irq, void *dev_id)
{
	ktime_t r, temp;
	unsigned int val = 0;
#ifdef REG_DEBUG
	unsigned long val_anacr2, val_cmc, val_auxen;
#endif

	printk ("%s: HS_BUTTONISR (<<<) : status=%d \n", __func__, mic.hsbst);

	if (mic.hsbst == DISABLE || mic.headset_state != HEADSET_4_POLE)
		return IRQ_HANDLED;

	/* Read the ANACR12 register value to check if the interrupt being
	* serviced by the ISR is spurious */
	val = readl(io_p2v(REG_ANACR12));
	temp = ktime_get();
	r = ktime_sub(temp,mic.hsbtime);
	if((r.tv.sec > 0) || (r.tv.nsec > REF_TIME))
	{
		mic.hsbtime = temp;
	}
	else
	{
		printk ("%s: HS_BUTTONISR appeared frequently (r.tv.sec=%d, r.tv.nsec=%d) status=%d \n", __func__, r.tv.sec, r.tv.nsec, mic.hsbst);
		// return IRQ_HANDLED;
	}
	/* If the value read from the ANACR12 register is greater than the
	* threshold, schedule the workqueue */
	printk("%s: REG_ANACR12=%x\n", __func__,val);

#ifdef REG_DEBUG
	val_anacr2 = readl(io_p2v(REG_ANACR2));
	val_cmc = readl(io_p2v(REG_AUXMIC_CMC));
	val_auxen = readl(io_p2v(REG_AUXMIC_AUXEN));
	printk("%s: REG_ANACR2=%x, REG_AUXMIC_CMC=%x, REG_AUXMIC_AUXEN=%x\n", __func__, val_anacr2, val_cmc, val_auxen);
#endif

	if (val >= KEY_PRESS_THRESHOLD)
	{
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE);

		key_resolved = 0;
		key_count[0] = key_count[1] = key_count[2] = 0;

		sync_use_mic = ENABLE;
		schedule_delayed_work(&(mic.input_work), KEY_BEFORE_PRESS_REF_TIME);
		printk("%s: set_button => PRESS\n", __func__);
		set_button(PRESS); 
	}
	else
	{
		pr_info("Headset Button press detected for a illegal interrupt\n");
		printk("%s: set_button => RELEASE\n", __func__);
		set_button(RELEASE);
	}

	printk ("%s: HS_BUTTONISR (>>>) : status=%d \n", __func__, mic.hsbst);

	return IRQ_HANDLED;
}
コード例 #22
0
static void input_work_func(struct work_struct *work)
{
	int delta = 0;
	unsigned long val = 0;
#ifdef REG_DEBUG
	unsigned long val_anacr2, val_cmc, val_auxen;
#endif
	static int key_status = RELEASE;
	int adc_value = auxadc_access(2);	
	printk("%s: input_work adc_value=%d\n", __func__, adc_value);

	/* If the key_status is 0, send the event for a key press */
	if(key_status == RELEASE)
	{
		delta = check_delta(mic.hsbtime,mic.hstime);
		if((mic.headset_state == HEADSET_4_POLE) && (delta == 0))
		{
			if (!key_resolved)
			{
				if ( adc_value >= KEY1_THRESHOLD_L && adc_value < KEY1_THRESHOLD_U )
				{
					key_count[0]++;
					if (key_count[0] >= KEYCOUNT_THRESHOLD)
						key_resolved = 1;
					key_type = KEY_BCM_HEADSET_BUTTON;
					printk ("KEY_BCM_HEADSET_BUTTON \n");
				}
				if ( adc_value >= KEY2_THRESHOLD_L && adc_value < KEY2_THRESHOLD_U ) 
				{	
					key_count[1]++;
					if (key_count[1] >= KEYCOUNT_THRESHOLD)
						key_resolved = 1;
					key_type = KEY_VOLUMEUP;
					printk ("KEY_VOLUMEUP \n");
				}
				if ( adc_value >= KEY3_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U ) 
				{
					key_count[2]++;
					if (key_count[2] >= KEYCOUNT_THRESHOLD)
						key_resolved = 1;
					key_type = KEY_VOLUMEDOWN;
					printk ("KEY_VOLUMEDOWN \n");
				}
			}
			else
				input_report_key(mic.headset_button_idev, key_type, PRESS);

			input_sync(mic.headset_button_idev);
			printk("%s: set_button => PRESS\n", __func__);
			set_button(PRESS);
			printk("%s: button pressed : ear_adc=%d\n", __func__, adc_value);
		}
	}

	/* Check if the value read from ANACR12 is greater than the
	* threshold. If so, the key is still pressed and schedule the work
	* queue till the value is less than the threshold */
	val = readl(io_p2v(REG_ANACR12));
	printk("%s: REG_ANACR12=%x\n", __func__,val);

	if (val >= KEY_PRESS_THRESHOLD && (adc_value >= KEY1_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U))
	{
		key_status = PRESS;

		if (!key_resolved)
		{
			if ( adc_value >= KEY1_THRESHOLD_L && adc_value < KEY1_THRESHOLD_U )
			{
				key_count[0]++;
				if (key_count[0] >= KEYCOUNT_THRESHOLD)
					key_resolved = 1;
				key_type = KEY_BCM_HEADSET_BUTTON;
				printk ("KEY_BCM_HEADSET_BUTTON\n");
			}
			if ( adc_value >= KEY2_THRESHOLD_L && adc_value < KEY2_THRESHOLD_U ) 
			{	
				key_count[1]++;
				if (key_count[1] >= KEYCOUNT_THRESHOLD)
					key_resolved = 1;
				key_type = KEY_VOLUMEUP;
				printk ("KEY_VOLUMEUP\n");
			}
			if ( adc_value >= KEY3_THRESHOLD_L && adc_value < KEY3_THRESHOLD_U ) 
			{
				key_count[2]++;
				if (key_count[2] >= KEYCOUNT_THRESHOLD)
					key_resolved = 1;
				key_type = KEY_VOLUMEDOWN;
				printk ("KEY_VOLUMEDOWN\n");
			}
		}
		else
			input_report_key(mic.headset_button_idev, key_type, PRESS);

		schedule_delayed_work(&(mic.input_work), KEY_PRESS_REF_TIME);
		printk("%s: set_button => PRESS\n", __func__);
		set_button(PRESS);
	}
	/* Once the value read from ANACR12 is less than the threshold, send
	* the event for a button release */
	else
	{
		key_status = RELEASE;
		printk ("%s: key_count [%d, %d, %d] \n", __func__, key_count[0], key_count[1], key_count[2]);

		if ( key_count[0] >= KEYCOUNT_THRESHOLD )
		{
			printk("SEND/END RELEASE\n");
			input_report_key(mic.headset_button_idev, KEY_BCM_HEADSET_BUTTON, RELEASE);
			input_sync(mic.headset_button_idev);
		}
		else if ( key_count[1] >= KEYCOUNT_THRESHOLD )
		{	
			printk("VOLUP RELEASE\n");
			input_report_key(mic.headset_button_idev, KEY_VOLUMEUP, RELEASE);
			input_sync(mic.headset_button_idev);
		}
		else if ( key_count[2] >= KEYCOUNT_THRESHOLD )
		{
			printk("VOLDOWN RELEASE\n");
			input_report_key(mic.headset_button_idev, KEY_VOLUMEDOWN, RELEASE);
			input_sync(mic.headset_button_idev);
		}

		printk("%s: set_button => RELEASE\n", __func__);
		set_button(RELEASE);	 
		key_resolved = 0;
		key_count[0] = key_count[1] = key_count[2] = 0;

		if(FactoryMode == DISABLE)
		{
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);
		sync_use_mic = DISABLE;
		}

#ifdef REG_DEBUG
		val_anacr2 = readl(io_p2v(REG_ANACR2));
		val_cmc = readl(io_p2v(REG_AUXMIC_CMC));
		val_auxen = readl(io_p2v(REG_AUXMIC_AUXEN));
		printk("%s: REG_ANACR2=%x, REG_AUXMIC_CMC=%x, REG_AUXMIC_AUXEN=%x\n", __func__, val_anacr2, val_cmc, val_auxen);
#endif
	}
}
コード例 #23
0
ファイル: brcm_headset.c プロジェクト: vM00/xm01
static int __init hs_probe(struct platform_device *pdev)
{
	int result = 0;
	mic.pluging = DISABLE;
	mic.keypressing = INIT;

	result = hs_switchinit(&mic);
	if (result < 0)
		return result;

	result = hs_inputdev(&mic);
	if (result < 0)
		goto err;

	INIT_DELAYED_WORK(&(mic.imsi_work), getIMSI_work_func);
	wake_lock_init(&mic.det_wake_lock, WAKE_LOCK_SUSPEND, "brcm_headset_det");
	mic.headset_workqueue = create_singlethread_workqueue("brcm_headset_wq");
	if (mic.headset_workqueue == NULL) {
		printk("%s: Failed to create workqueue\n", __func__);
		goto err1;
	}

	/* check if platform data is defined for a particular board variant */
	if (pdev->dev.platform_data)
	{
		mic.headset_pd = pdev->dev.platform_data;

		KEY_PRESS_THRESHOLD = mic.headset_pd->key_press_threshold;
		KEY_3POLE_THRESHOLD = mic.headset_pd->key_3pole_threshold;
		KEY1_THRESHOLD_L = mic.headset_pd->key1_threshold_l;
		KEY1_THRESHOLD_U = mic.headset_pd->key1_threshold_u;
		KEY2_THRESHOLD_L = mic.headset_pd->key2_threshold_l;
		KEY2_THRESHOLD_U = mic.headset_pd->key2_threshold_u;
		KEY3_THRESHOLD_L = mic.headset_pd->key3_threshold_l;
		KEY3_THRESHOLD_U = mic.headset_pd->key3_threshold_u;
		
		if (gpio_request(mic.headset_pd->hsgpio, "headset detect") < 0)
		{
			printk("%s: Could not reserve headset signal GPIO!\n", __func__);
			goto err2;
		}
		
		gpio_direction_input(mic.headset_pd->hsgpio);
		bcm_gpio_set_db_val(mic.headset_pd->hsgpio, 0x7);
		mic.headset_pd->hsirq = gpio_to_irq(mic.headset_pd->hsgpio);		
	}
    	else
	{
		goto err2;
	}

	/* Set the ANACR2 bit for mic power down */
	board_sysconfig(SYSCFG_AUXMIC, SYSCFG_INIT);
	board_sysconfig(SYSCFG_HEADSET, SYSCFG_INIT);

	/*Fix the audio path is wrong when headset already plugged in the device  then boot device case.*/
	mic.headset_pd->check_hs_state(&mic.headset_state);
	set_irq_type(mic.headset_pd->hsirq, (mic.headset_state) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
	determine_state_func();	
	queue_delayed_work(mic.headset_workqueue, &(mic.imsi_work), GET_IMSI_REF_TIME);

	result = request_threaded_irq(mic.headset_pd->hsbirq, NULL, hs_buttonisr,  (IRQF_ONESHOT |IRQF_NO_SUSPEND), "BrcmHeadsetButton",  NULL);
	if(result < 0)
		goto err2;

	DISABLE_IRQ_MICON;

	result = request_threaded_irq(mic.headset_pd->hsirq, NULL, hs_isr, (IRQF_ONESHOT|IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND), "BrcmHeadset",  NULL);
	if(result < 0)
	{
		free_irq(mic.headset_pd->hsbirq, &mic);
		goto err2;
	}
	enable_irq_wake(mic.headset_pd->hsirq);
	set_irq_type(mic.headset_pd->hsirq, (mic.headset_state) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);

	return 0;

err2:  destroy_workqueue(mic.headset_workqueue);	
err1:  input_unregister_device(mic.headset_button_idev);
err: switch_dev_unregister(&mic.sdev);
	return result;
}
コード例 #24
0
/****************************************************************************
*
*  lcd_dev_dirty_rect
*
*   Marks the indicated rows as dirty and arranges for them to be transferred
*   to the LCD.
*
***************************************************************************/
static void lcd_dev_dirty_rect(LCD_dev_info_t * dev,
			       LCD_DirtyRect_t * dirtyRect)
{
	CSL_LCD_RES_T ret;
	int i;
	int err = -EINVAL;

	OSDAL_Dma_Buffer_List *buffer_list, *temp_list;

    if (unlikely(ap_crashed)) {
        return;
    }

    if(!dev) {
        pr_info("dev pointer is NULL\n");
        return;
    }
    if(!dirtyRect) {
        pr_info("dirtyRect pointer is NULL\n");
        return;
    }
	if ((dirtyRect->top > dirtyRect->bottom)
	    || ((dirtyRect->bottom - dirtyRect->top) >= dev->height)
	    || (dirtyRect->left > dirtyRect->right)
	    || ((dirtyRect->right - dirtyRect->left) >= dev->width)) {
		LCD_DEBUG("invalid dirty-rows params - ignoring\n");
		LCD_DEBUG("top = %u,  bottom = %u, left = %u, right = %u\n",
			  dirtyRect->top, dirtyRect->bottom,
			  dirtyRect->left, dirtyRect->right);
		return;
	}

	down_interruptible(&gDmaSema);
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock(&glcdfb_wake_lock);
#endif

	dev->dirty_rect = *dirtyRect;
	dev->row_start = dev->dirty_rect.top % dev->height;
	dev->row_end = dev->dirty_rect.bottom % dev->height;

	/*If start address is aligned to odd boundary */
	if (is_unaligned(dev)) {
		dev->col_start = dev->dirty_rect.left;
		dev->col_end = dev->dirty_rect.left;
		lcd_setup_for_data(dev);
		lcd_update_column(dev, dev->dirty_rect.left);
		dev->dirty_rect.left += 1;
	}

	/*If length is odd multiple */
	if (is_odd_stride(dev) || ((dev->bits_per_pixel == 32) && is_odd_total(dev))) {
		dev->col_start = dev->dirty_rect.right;
		dev->col_end = dev->dirty_rect.right;
		lcd_setup_for_data(dev);
		lcd_update_column(dev, dev->dirty_rect.right);
		dev->dirty_rect.right -= 1;
	}

	if (is_out_of_bounds(dev) || ((32 != dev->bits_per_pixel) && is_tx_done_16(dev))
		|| ((32 == dev->bits_per_pixel) && is_tx_done_32(dev))) {
		/* Dirty columns have been transferred. No further processing required.*/
		goto done;
	}

	buffer_list = kzalloc((dev->dirty_rect.bottom - dev->dirty_rect.top + 1) * sizeof(OSDAL_Dma_Buffer_List), GFP_KERNEL);
	if (!buffer_list) {
		pr_info("Couldn't allocate memory for dma buffer list\n");
		goto done;
	}

	temp_list = buffer_list;
	for (i = dev->dirty_rect.top; i <= dev->dirty_rect.bottom; i++) {
		temp_list->buffers[0].srcAddr = (UInt32)dev->frame_buffer.physPtr + (i * dev->width + dev->dirty_rect.left) * dev->bits_per_pixel / 8;
		temp_list->buffers[0].destAddr = REG_LCDC_DATR_PADDR;
		temp_list->buffers[0].length =
		    (dev->dirty_rect.right - dev->dirty_rect.left +
		     1) * dev->bits_per_pixel / 8;
		temp_list->buffers[0].bRepeat = 0;
		temp_list++;
	}
	temp_list--;		/* Go back to the last list item to set interrupt = 1 */
	temp_list->buffers[0].interrupt = 1;

	req.buff = (void *)buffer_list;
	req.buffBpp = dev->bits_per_pixel;
	req.lineLenP = dev->dirty_rect.right - dev->dirty_rect.left + 1;
	req.lineCount = dev->dirty_rect.bottom - dev->dirty_rect.top + 1;
	req.timeOut_ms = 100;
	req.cslLcdCb = lcd_csl_cb;
	req.cslLcdCbRef = NULL;
	req.multiLLI = true;

	dev->col_start = dev->dirty_rect.left;
	dev->col_end = dev->dirty_rect.right;

	lcd_setup_for_data(dev);

//    if(hsm_supported && window_hsm_compatible(dev->dirty_rect))
//        CSL_LCDC_PAR_SetSpeed(handle, &timingMem_hs);
//    else
        CSL_LCDC_PAR_SetSpeed(handle, &timingMem);

	/*CP processor is setting IOCR6[19], which it shouldn't be doing. Remove this once the CP team fixes it.*/
	if (dev->te_supported) {
		board_sysconfig(SYSCFG_LCD, SYSCFG_ENABLE);
	}

	ret = CSL_LCDC_Update(handle, &req);
	if (CSL_LCD_OK != ret) {
		pr_info("CSL_LCDC_Update failed error: %d", ret);
		goto fail;
	}
	err = 0;

fail:
	kfree(buffer_list);

done:
#ifdef CONFIG_HAS_WAKELOCK
	wake_unlock(&glcdfb_wake_lock);
#endif
	if (err < 0)
		up(&gDmaSema);
}