コード例 #1
0
static int ear_switch_change(struct work_struct *ignored)
{
	int ear_state = 0;

	SEC_HEADSET_DBG("");
	if(!ip_dev){
    		dev_err(ip_dev->dev.parent,"Input Device not allocated\n");
    		return IRQ_HANDLED;
  	}
  
  	ear_state = gpio_get_value(EAR_KEY_GPIO) ^ EAR_KEY_INVERT_ENABLE;
	
  	if( ear_state < 0 ){
    	dev_err(ip_dev->dev.parent,"Failed to read GPIO value\n");
    	return IRQ_HANDLED;
  	}

	del_timer(&send_end_key_event_timer);
	send_end_key_timer_token = 0;	

	//gpio_direction_output(EAR_ADC_SEL_GPIO , 0);

	if((get_headset_status() == HEADSET_4POLE_WITH_MIC) && send_end_irq_token)//  4 pole headset connected && send irq enable
	{
		if(ear_state)
		{
			send_end_key_event_timer.expires = SEND_END_CHECK_TIME; // 10ms ??
			add_timer(&send_end_key_event_timer);		
			SEC_HEADSET_DBG("SEND/END %s.timer start \n", "pressed");
			
		}else{
			SEC_HEADSET_DBG(KERN_ERR "SISO:sendend isr work queue\n");    			
		 	input_report_key(ip_dev,KEYCODE_HEADSETHOOK,0);
  			input_sync(ip_dev);
			printk("SEND/END %s.\n", "released");
			earkey_stats = 0;
			switch_set_state(&switch_sendend, 0);
			//gpio_direction_output(EAR_ADC_SEL_GPIO , 1);
		}

	}else{
		SEC_HEADSET_DBG("SEND/END Button is %s but headset disconnect or irq disable.\n", ear_state?"pressed":"released");
	}

  return 0;
}
コード例 #2
0
static void send_end_key_event_timer_handler(unsigned long arg)
{
	int sendend_state = 0;
	int adc_val = 0;	
  int i = 0;

	SEC_HEADSET_DBG("  ");
	sendend_state = gpio_get_value(EAR_KEY_GPIO) ^ EAR_KEY_INVERT_ENABLE;

	if((get_headset_status() == HEADSET_4POLE_WITH_MIC) && sendend_state)
	{
		if(send_end_key_timer_token < SEND_END_CHECK_COUNT)
		{	
			send_end_key_timer_token++;
			send_end_key_event_timer.expires = SEND_END_CHECK_TIME; 
			add_timer(&send_end_key_event_timer);

			schedule_delayed_work(&check_key_adc_work, 0);
	    
			SEC_HEADSET_DBG("SendEnd Timer Restart %d", send_end_key_timer_token);
		}
		else if(send_end_key_timer_token == SEND_END_CHECK_COUNT)
		{
			printk("SEND/END is pressed\n");
			earkey_stats = 1;
			schedule_delayed_work(&release_sysfs_event_work, 0);
			send_end_key_timer_token = 0;
		}
		else
		{
			printk(KERN_ALERT "[Headset]wrong timer counter %d\n", send_end_key_timer_token);
			//gpio_direction_output(EAR_ADC_SEL_GPIO , 1);
		}
	}
	else
	{		
		printk(KERN_ALERT "[Headset]GPIO Error\n %d, %d", get_headset_status(), sendend_state);
		check_adc = 0;
    count = 0;
    
  	for(i = 0 ; i < SEND_END_CHECK_COUNT ; i++)
  	  adc_buffer[i] = 0;

		//gpio_direction_output(EAR_ADC_SEL_GPIO , 1);
	}
}
コード例 #3
0
void ear_key_disable_irq(void)
{
	SEC_HEADSET_DBG("  ");
	if(send_end_irq_token > 0)
	{
		//disable_irq(EAR_KEY_GPIO);
		send_end_irq_token--;
	}else{
		printk("[EAR_KEY]Err!! send_end_irq_toke is < 0\n");
	}
}
コード例 #4
0
static void gpio_switch_work(struct work_struct *work)
{
    int state;
    SEC_HEADSET_DBG("");
    //struct gpio_switch_data	*data =
    //container_of(work, struct gpio_switch_data, work);
    del_timer(&headset_detect_timer);
    cancel_delayed_work_sync(&ear_adc_cal_work);

    state = gpio_get_value(data->gpio) ^ EAR_DETECT_INVERT_ENABLE;

    if (state || !state)
    {
        //wake_lock(&headset_sendend_wake_lock);
        SEC_HEADSET_DBG("Headset attached timer start");
        headset_detect_timer_token = 0;
        headset_detect_timer.expires = HEADSET_CHECK_TIME;
        add_timer(&headset_detect_timer);
    }

    else
        SEC_HEADSET_DBG("Headset state does not valid. or send_end event");
}
コード例 #5
0
static int __devexit ear_key_driver_remove(struct platform_device *plat_dev)
{
  //struct input_dev *ip_dev= platform_get_drvdata(plat_dev);
	int ear_key_irq=0;

	SEC_HEADSET_DBG("");
	ear_key_irq = platform_get_irq(plat_dev,0);
  
	free_irq(ear_key_irq,ip_dev);
	switch_dev_unregister(&switch_sendend);
	input_unregister_device(ip_dev);  

	 return 0;
}
コード例 #6
0
void release_ear_key(void)
{
	SEC_HEADSET_DBG("  ");
	if(earkey_stats)
	{
		printk("Headset detached and earkey was pressed!\n");
		input_report_key(ip_dev,KEYCODE_HEADSETHOOK,0);
  		input_sync(ip_dev);
		printk("SEND/END %s.\n", "released");
		earkey_stats = 0;
		switch_set_state(&switch_sendend, 0);
		//gpio_direction_output(EAR_ADC_SEL_GPIO , 1);
	}
}
コード例 #7
0
static void headset_detect_timer_handler(unsigned long arg)
{
    int state;
    int count = 0;
    state = gpio_get_value(data->gpio) ^ EAR_DETECT_INVERT_ENABLE;
    if(state)
        count = HEADSET_ATTACH_COUNT;
    else if(!state)
        count = HEADSET_DETACH_COUNT;

    SEC_HEADSET_DBG("Check attach state - headset_detect_timer_token is %d", headset_detect_timer_token);

    if(headset_detect_timer_token < count)
    {
        //gpio_direction_output(EAR_ADC_SEL_GPIO , 0);

        headset_detect_timer.expires = HEADSET_CHECK_TIME;
        add_timer(&headset_detect_timer);
        headset_detect_timer_token++;
    }
    else if(headset_detect_timer_token == count)
    {

        schedule_delayed_work(&ear_adc_cal_work, 20);
        SEC_HEADSET_DBG("add work queue - timer token is %d", count);
        headset_detect_timer_token = 0;
    }
    else
    {
        printk(KERN_ALERT "wrong headset_detect_timer_token count %d", headset_detect_timer_token);
        gpio_direction_output(EAR_MIC_BIAS_GPIO, 0);
    }



}
コード例 #8
0
static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf)
{
    struct gpio_switch_data	*switch_data =
        container_of(sdev, struct gpio_switch_data, sdev);
    const char *state;
    SEC_HEADSET_DBG("");
    if (switch_get_state(sdev))
        state = switch_data->state_on;
    else
        state = switch_data->state_off;

    if (state)
        return sprintf(buf, "%s\n", state);
    return -1;
}
コード例 #9
0
static int __devexit gpio_switch_remove(struct platform_device *pdev)
{
    struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);
    SEC_HEADSET_DBG("");
    cancel_work_sync(&switch_data->work);
    gpio_free(switch_data->gpio);
    switch_dev_unregister(&switch_data->sdev);
#ifdef USE_REGULATOR
    regulator_put(usb3v1);
    regulator_put(vintana2)
#endif
    kfree(switch_data);

    return 0;
}
コード例 #10
0
static irqreturn_t earkey_press_handler(int irq_num, void * dev)
{
	SEC_HEADSET_DBG("earkey isr");
	if(send_end_irq_token)
	{
		if((gpio_get_value(EAR_KEY_GPIO) ^ EAR_KEY_INVERT_ENABLE))
			schedule_work(&fast_check_key_adc_work);

		schedule_work(&ear_switch_work);
	}
	else
	{
		printk("send end irq ries but token is null\n");
	}
	return IRQ_HANDLED;
}
コード例 #11
0
static int get_adc_data( int ch )
{
	int ret = 0;
	struct twl4030_madc_request req;
	SEC_HEADSET_DBG("  ");
    
	req.channels = ( 1 << ch );
	req.do_avg = 0;
	req.method = TWL4030_MADC_SW1;
	req.active = 0;
	req.func_cb = NULL;
	twl4030_madc_conversion( &req );

	ret = req.rbuf[ch];
	//printk("adc value is : %d", ret);

	return ret;
}
コード例 #12
0
static void check_key_adc(unsigned long arg)
{
	int adc_val;

	SEC_HEADSET_DBG("  ");
	adc_val = get_adc_data(3);
	//printk("- Earkey pressed ADC %d\n" , adc_val);
	
	if(adc_val <= 150 && adc_val >= 75)
	{
		printk("[Earkey]adc is within %d\n", adc_val);
		check_adc++;
	}
	else
	{
		printk("[Earkey]adc is NOT within %d\n", adc_val);
	}

	adc_buffer[count++] = adc_val;
}
コード例 #13
0
static void fast_check_key_adc(unsigned long arg)
{
	fast_adc_val = 0;
    fast_adc_avg_val = 0;
    
	SEC_HEADSET_DBG("  ");

    //gpio_direction_output(EAR_ADC_SEL_GPIO , 0);	
    
	fast_adc_val = get_adc_data(3);
	//printk("fast_check_key_adc() ADC value is = %d\n" , fast_adc_val);

    fast_adc_val += get_adc_data(3);
	//printk("fast_check_key_adc() ADC value is = %d\n" , fast_adc_val);

	fast_adc_avg_val = fast_adc_val / 2;
	printk("fast_key_adc() avg_val is = %d\n" , fast_adc_avg_val);
	
    //gpio_direction_output(EAR_ADC_SEL_GPIO , 1);		
}
コード例 #14
0
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
    struct gpio_switch_data *switch_data =
        (struct gpio_switch_data *)dev_id;
#ifdef CONFIG_INPUT_ZEUS_EAR_KEY
    int state;

    wake_lock_timeout(&headset_wake_lock, 3*HZ);

    SEC_HEADSET_DBG("");
    state = gpio_get_value(data->gpio) ^ EAR_DETECT_INVERT_ENABLE;
    if (!state)
    {
        printk("[Headset] disable earkey\n");
        ear_key_disable_irq();
    }
#endif
    gpio_direction_output(EAR_MIC_BIAS_GPIO, 0);
    schedule_work(&switch_data->work);
    return IRQ_HANDLED;
}
コード例 #15
0
static void release_sysfs_event(unsigned long arg)
{
    int i = 0;
    bool result = false;
  
	SEC_HEADSET_DBG(" %d ", earkey_stats);

    for(i = 0 ; i < SEND_END_CHECK_COUNT ; i++)
    {
        if(adc_buffer[i] >= 75)
        {
            result = false;
            break;
        }
        else
        {
            result = true;
        }
    }

    if((check_adc >= 2 ) || ((fast_adc_avg_val < 100) && (result == true)))
	{
		input_report_key(ip_dev,KEYCODE_HEADSETHOOK,1);
		input_sync(ip_dev);	
	}

	check_adc = 0;
    count = 0;

    for(i = 0 ; i < SEND_END_CHECK_COUNT ; i++)
        adc_buffer[i] = 0;
	
	if(earkey_stats)
		switch_set_state(&switch_sendend, 1);
	else
		switch_set_state(&switch_sendend, 0);

	//gpio_direction_output(EAR_ADC_SEL_GPIO , 1);

}
コード例 #16
0
short int get_headset_status(void)
{
    SEC_HEADSET_DBG(" headset_status %d", headset_status);
    return headset_status;
}
コード例 #17
0
static int gpio_switch_probe(struct platform_device *pdev)
{
    struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;
    struct gpio_switch_data *switch_data;
    int ret = 0;
    SEC_HEADSET_DBG("");
    this_dev = &pdev->dev;

    if (gpio_request(EAR_MIC_BIAS_GPIO, "EARMIC") == 1)
    {
        gpio_direction_output(EAR_MIC_BIAS_GPIO, 0);
    }

    if (!pdata)
        return -EBUSY;

    switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL);
    if (!switch_data)
        return -ENOMEM;
#ifdef USE_REGULATOR
    usb3v1 = regulator_get(this_dev, "usb3v1");
    if (IS_ERR(usb3v1))
        return -ENODEV;
    vintana2 = regulator_get(this_dev, "vintana2");
    if (IS_ERR(vintana2))
        return -ENODEV;
#endif
    switch_data->sdev.name = pdata->name;
    switch_data->gpio = pdata->gpio;
    switch_data->name_on = pdata->name_on;
    switch_data->name_off = pdata->name_off;
    switch_data->state_on = pdata->state_on;
    switch_data->state_off = pdata->state_off;
    switch_data->sdev.print_state = switch_gpio_print_state;

    ret = switch_dev_register(&switch_data->sdev);
    if (ret < 0)
        goto err_switch_dev_register;

    ret = gpio_request(switch_data->gpio, pdev->name);
    if (ret < 0)
        goto err_request_gpio;

    ret = gpio_direction_input(switch_data->gpio);
    if (ret < 0)
        goto err_set_gpio_input;

    INIT_WORK(&switch_data->work, gpio_switch_work);

    switch_data->irq = gpio_to_irq(switch_data->gpio);
    if (switch_data->irq < 0) {
        ret = switch_data->irq;
        goto err_detect_irq_num_failed;
    }

    ret = request_irq(switch_data->irq, gpio_irq_handler,
                      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                      pdev->name,
                      switch_data); //Iyyappan_HS
    if (ret < 0)
        goto err_request_irq;
    data = switch_data;

    init_timer(&headset_detect_timer);
    headset_detect_timer.function = headset_detect_timer_handler;

    wake_lock_init(&headset_wake_lock, WAKE_LOCK_SUSPEND, "headset");

    enable_irq_wake(switch_data->irq);

    /* Perform initial detection */
    gpio_switch_work(&switch_data->work);

    return 0;

err_request_irq:
err_detect_irq_num_failed:
err_set_gpio_input:
    gpio_free(switch_data->gpio);
err_request_gpio:
    switch_dev_unregister(&switch_data->sdev);
err_switch_dev_register:
    kfree(switch_data);

    return ret;
}
コード例 #18
0
static int __devinit ear_key_driver_probe(struct platform_device *plat_dev)
{
  struct input_dev *ear_key=NULL;
  int ear_key_irq=-1, err=0;

  SEC_HEADSET_DBG("");
  ear_key_irq = platform_get_irq(plat_dev, 0);
  if(ear_key_irq <= 0 ){
    dev_err(&plat_dev->dev,"failed to map the ear key to an IRQ %d\n",ear_key_irq);
    err = -ENXIO;
    return err;
  }
  ear_key = input_allocate_device();
  if(!ear_key)
  {
    dev_err(&plat_dev->dev,"failed to allocate an input devd %d \n",ear_key_irq);
    err = -ENOMEM;
    return err;
  }
  err = request_irq(ear_key_irq, &earkey_press_handler ,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
                    "ear_key_driver",ear_key);
  if(err) {
    dev_err(&plat_dev->dev,"failed to request an IRQ handler for num %d\n",ear_key_irq);
    goto free_input_dev;
  }
  dev_dbg(&plat_dev->dev,"\n ear Key Drive:Assigned IRQ num %d SUCCESS \n",ear_key_irq);
  /* register the input device now */
  set_bit(EV_SYN,ear_key->evbit);
  set_bit(EV_KEY,ear_key->evbit);
  set_bit(KEYCODE_HEADSETHOOK, ear_key->keybit);

  ear_key->name = "ear_key_driver";
  ear_key->phys = "ear_key_driver/input0";
  ear_key->dev.parent = &plat_dev->dev;
  platform_set_drvdata(plat_dev, ear_key);

  err = input_register_device(ear_key);
  if (err) {
    dev_err(&plat_dev->dev, "ear key couldn't be registered: %d\n", err);
    goto release_irq_num;
  }
  	err = switch_dev_register(&switch_sendend);
	if (err < 0) {
		printk(KERN_ERR "SEC HEADSET: Failed to register switch sendend device\n");
		goto free_input_dev;
        }
	//disable_irq(EAR_KEY_GPIO);

	init_timer(&send_end_key_event_timer);
	send_end_key_event_timer.function = send_end_key_event_timer_handler;
	ip_dev = ear_key;

  return 0;

release_irq_num:
	free_irq(ear_key_irq,NULL); //pass devID as NULL as device registration failed 

free_input_dev:
	input_free_device(ear_key);

return err;

}
コード例 #19
0
void ear_key_enable_irq(void)
{
	SEC_HEADSET_DBG("  ");
	//enable_irq(EAR_KEY_GPIO);
	send_end_irq_token++;
}