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; }
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); } }
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"); } }
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"); }
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; }
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); } }
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); } }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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); }
short int get_headset_status(void) { SEC_HEADSET_DBG(" headset_status %d", headset_status); return headset_status; }
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; }
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; }
void ear_key_enable_irq(void) { SEC_HEADSET_DBG(" "); //enable_irq(EAR_KEY_GPIO); send_end_irq_token++; }