static irqreturn_t acc_ID_interrupt(int irq, void *dev_id) { struct acc_con_info *acc = (struct acc_con_info *)dev_id; int acc_ID_val = 0, pre_acc_ID_val = 0; int time_left_ms = DET_CHECK_TIME_MS; ACC_CONDEV_DBG(""); while (time_left_ms > 0) { acc_ID_val = acc->pdata->get_dock_state(); if (acc_ID_val == pre_acc_ID_val) time_left_ms -= DET_SLEEP_TIME_MS; else time_left_ms = DET_CHECK_TIME_MS; pre_acc_ID_val = acc_ID_val; msleep(DET_SLEEP_TIME_MS); } ACC_CONDEV_DBG("IRQ_DOCK_GPIO is %d", acc_ID_val); if (acc_ID_val == 0) { ACC_CONDEV_DBG("Accessory detached"); acc_notified(acc, false); } else { wake_lock(&acc->wake_lock); schedule_delayed_work(&acc->acc_id_dwork, msecs_to_jiffies(DETECTION_DELAY_MS)); } return IRQ_HANDLED; }
void acc_con_intr_handle(struct work_struct *_work) { //ACC_CONDEV_DBG(""); //check the flag MHL or keyboard int cur_state = gpio_get_value(GPIO_ACCESSORY_INT); if(cur_state !=DOCK_STATE) { if(1==cur_state) { ACC_CONDEV_DBG("docking station detatched!!!"); DOCK_STATE = cur_state; #if defined(CONFIG_KEYBOARD_P1) check_keyboard_dock(); #endif #ifdef CONFIG_MHL_SII9234 //call MHL deinit MHD_HW_Off(); //msleep(120); //max8998_ldo3_8_control(0,LDO_TV_OUT); //ldo 3,8 off //printk("%s: LDO3_8 is disabled by TV \n", __func__); TVout_LDO_ctrl(false); #endif acc_dock_check(CONNECTED_DOCK , DOCK_STATE); CONNECTED_DOCK = 0; } else if(0==cur_state) { ACC_CONDEV_DBG("docking station attatched!!!"); DOCK_STATE = cur_state; #if defined(CONFIG_KEYBOARD_P1) if(check_keyboard_dock()) { CONNECTED_DOCK = DOCK_KEYBD; } else #endif { #ifdef CONFIG_MHL_SII9234 CONNECTED_DOCK = DOCK_DESK; //max8998_ldo3_8_control(1,LDO_TV_OUT); //ldo 3,8 on //printk("%s: LDO3_8 is enabled by TV \n", __func__); //msleep(120); TVout_LDO_ctrl(true); //call MHL init sii9234_tpi_init(); #endif } acc_dock_check(CONNECTED_DOCK , DOCK_STATE); } } else { ACC_CONDEV_DBG("Ignored"); } enable_irq(IRQ_ACCESSORY_INT); }
static void acc_check_dock_detection(struct acc_con_info *acc) { if (NULL == acc->pdata->get_dock_state) { ACC_CONDEV_DBG("[30PIN] failed to get acc state!!!"); return; } if (!acc->pdata->get_dock_state()) { #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard && acc->pdata->check_keyboard(true)) { acc->current_dock = DOCK_KEYBOARD; ACC_CONDEV_DBG ("[30PIN] keyboard dock station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_KEYBOARD); } else #endif { ACC_CONDEV_DBG ("[30PIN] desktop dock station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_DESK); acc->current_dock = DOCK_DESK; #ifdef CONFIG_MHL_SII9234 mutex_lock(&acc->lock); if (!acc->mhl_pwr_state) { sii9234_tpi_init(); acc->mhl_pwr_state = true; } mutex_unlock(&acc->lock); #endif } acc_dock_uevent(acc, true); } else { ACC_CONDEV_DBG("[30PIN] dock station detached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_NONE); #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard) acc->pdata->check_keyboard(false); #endif #ifdef CONFIG_MHL_SII9234 /*call MHL deinit */ if (acc->mhl_pwr_state) { MHD_HW_Off(); acc->mhl_pwr_state = false; } #endif /*TVout_LDO_ctrl(false); */ acc_dock_uevent(acc, false); } }
static void acc_check_dock_detection(struct acc_con_info *acc) { if (!acc->pdata->get_dock_state()) { // ACC_CONDEV_DBG("[30PIN] failed to get acc state!!!"); wake_lock(&acc->wake_lock); #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard && acc->pdata->check_keyboard(true)) { acc->current_dock = DOCK_KEYBOARD; ACC_CONDEV_DBG ("[30PIN] keyboard dock station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_KEYBOARD); } else #endif { ACC_CONDEV_DBG ("[30PIN] desktop dock station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_DESK); acc->current_dock = DOCK_DESK; } #ifdef CONFIG_MHL_SII9234 mutex_lock(&acc->lock); sii9234_tpi_init(); hdmi_msm_hpd_switch(true); mutex_unlock(&acc->lock); #endif acc_dock_uevent(acc, true); wake_unlock(&acc->wake_lock); } else { if (acc->current_dock == DOCK_NONE) return; ACC_CONDEV_DBG("docking station detached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_NONE); acc_dock_uevent(acc, false); #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard) acc->pdata->check_keyboard(false); #endif #ifdef CONFIG_MHL_SII9234 /*call MHL deinit */ MHD_HW_Off(); hdmi_msm_hpd_switch(false); /*TVout_LDO_ctrl(false); */ #endif } }
static int acc_get_accessory_id(void) { int i; u32 adc = 0, adc_sum = 0; u32 adc_buff[5] = {0}; u32 adc_val; u32 adc_min = 0; u32 adc_max = 0; for (i = 0; i < 5; i++) { /*change this reading ADC function */ //// tps6586x_adc_read(&mili_volt, 0); adc_val=acc_get_adc_value(); adc_buff[i] = adc_val; adc_sum += adc_buff[i]; if (i == 0) { adc_min = adc_buff[0]; adc_max = adc_buff[0]; } else { if (adc_max < adc_buff[i]) adc_max = adc_buff[i]; else if (adc_min > adc_buff[i]) adc_min = adc_buff[i]; } msleep(20); } adc = (adc_sum - adc_max - adc_min)/3; ACC_CONDEV_DBG("ACCESSORY_ID : ADC value = %d\n", adc); return (int)adc; }
static int connector_detect_change(void) { int adc = 0,i,adc_sum=0; int adc_buff[5]={0}; int adc_min=0; int adc_max=0; for(i = 0; i < 5; i++) { adc_buff[i] = s3c_adc_get_adc_data(ACCESSORY_ID); adc_sum +=adc_buff[i]; if(i == 0) { adc_min = adc_buff[0]; adc_max = adc_buff[0]; } else { if(adc_max < adc_buff[i]) adc_max = adc_buff[i]; else if(adc_min > adc_buff[i]) adc_min = adc_buff[i]; } msleep(20); } adc = (adc_sum - adc_max - adc_min)/3; ACC_CONDEV_DBG("ACCESSORY_ID : ADC value = %d\n", adc); return adc; }
static void acc_dock_uevent(struct acc_con_info *acc, bool connected) { char *env_ptr; char *stat_ptr; char *envp[3]; if (acc->current_dock == DOCK_KEYBOARD) env_ptr = "DOCK=keyboard"; else if (acc->current_dock == DOCK_DESK) env_ptr = "DOCK=desk"; else env_ptr = "DOCK=unknown"; if (!connected) { stat_ptr = "STATE=offline"; acc->current_dock = DOCK_NONE; } else { stat_ptr = "STATE=online"; } envp[0] = env_ptr; envp[1] = stat_ptr; envp[2] = NULL; kobject_uevent_env(&acc->acc_dev->kobj, KOBJ_CHANGE, envp); ACC_CONDEV_DBG("%s : %s", env_ptr, stat_ptr); }
static int acc_get_accessory_id(struct acc_con_info *acc) { int i; u32 adc = 0, adc_sum = 0; u32 adc_buff[5] = {0}; u32 adc_val = 0; u32 adc_min = 0; u32 adc_max = 0; if (!acc || !acc->padc) { pr_err("adc client is not registered!\n"); return -1; } for (i = 0; i < 5; i++) { adc_val = acc_get_adc_accessroy_id(acc->padc); adc_buff[i] = adc_val; adc_sum += adc_buff[i]; if (i == 0) { adc_min = adc_buff[0]; adc_max = adc_buff[0]; } else { if (adc_max < adc_buff[i]) adc_max = adc_buff[i]; else if (adc_min > adc_buff[i]) adc_min = adc_buff[i]; } msleep(20); } adc = (adc_sum - adc_max - adc_min)/3; ACC_CONDEV_DBG("ACCESSORY_ID ADC value = %d", adc); return (int)adc; }
static int connector_detect_change(void) { int i; u32 adc = 0, adc_sum = 0; u32 adc_buff[5] = {0}; u32 mili_volt; u32 adc_min = 0; u32 adc_max = 0; for (i = 0; i < 5; i++) { /*change this reading ADC function */ mili_volt = (u32)stmpe811_adc_get_value(7); adc_buff[i] = mili_volt; adc_sum += adc_buff[i]; if (i == 0) { adc_min = adc_buff[0]; adc_max = adc_buff[0]; } else { if (adc_max < adc_buff[i]) adc_max = adc_buff[i]; else if (adc_min > adc_buff[i]) adc_min = adc_buff[i]; } msleep(20); } adc = (adc_sum - adc_max - adc_min)/3; ACC_CONDEV_DBG("ACCESSORY_ID : ADC value = %d\n", adc); return (int)adc; }
void acc_MHD_intr_handle(struct work_struct *_work) { int val = gpio_get_value(GPIO_MHL_INT); ACC_CONDEV_DBG("++GPIO_MHL_INT = %x",val); MHD_Bridge_detect(); enable_irq(IRQ_MHL_INT); }
static void acc_id_delay_work(struct work_struct *work) { struct acc_con_info *acc = container_of(work, struct acc_con_info, acc_id_dwork.work); int adc_val = 0; if (!acc->pdata->get_dock_state()) { ACC_CONDEV_DBG("ACCESSORY detached\n"); wake_unlock(&acc->wake_lock); return; } else { ACC_CONDEV_DBG("Accessory attached"); adc_val = connector_detect_change(); ACC_CONDEV_DBG("adc_val : %d", adc_val); acc_notified(acc, adc_val); } wake_unlock(&acc->wake_lock); }
static int acc_init_accessory_int(struct acc_con_info *acc) { int ret = 0; acc->dock_irq = gpio_to_irq(acc->pdata->dock_irq_gpio); ret = request_threaded_irq(acc->dock_irq, NULL, acc_accessory_isr, IRQF_ONESHOT | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "dock_detect", acc); if (ret) ACC_CONDEV_DBG("request_irq(dock_irq) return : %d\n", ret); ret = enable_irq_wake(acc->dock_irq); if (ret) ACC_CONDEV_DBG("enable_irq_wake(dock_irq) return : %d\n", ret); return ret; }
static void check_acc_dock(struct acc_con_info *acc) { if (gpio_get_value(acc->pdata->accessory_irq_gpio)) { if (acc->current_dock == DOCK_NONE) return; ACC_CONDEV_DBG("docking station detached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_NONE); #ifdef CONFIG_SEC_KEYBOARD_DOCK acc->pdata->check_keyboard(false); #endif #if defined(CONFIG_VIDEO_MHL_TAB_V2) /*call MHL deinit */ mhl_onoff_ex(false); #endif acc_dock_check(acc, false); } else { ACC_CONDEV_DBG("docking station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_CONNECTED); msleep(100); wake_lock(&acc->wake_lock); #ifdef CONFIG_SEC_KEYBOARD_DOCK if (acc->pdata->check_keyboard(true)) { acc->current_dock = DOCK_KEYBOARD; ACC_CONDEV_DBG("[30PIN] keyboard dock " "station attached!!!"); switch_set_state(&acc->dock_switch, UEVENT_DOCK_KEYBOARD); } else #endif /* CONFIG_SEC_KEYBOARD_DOCK */ { switch_set_state(&acc->dock_switch, UEVENT_DOCK_DESK); acc->current_dock = DOCK_DESK; } #if defined(CONFIG_VIDEO_MHL_TAB_V2) mhl_onoff_ex(true); #endif acc_dock_check(acc, true); wake_unlock(&acc->wake_lock); } }
static irqreturn_t acc_accessory_isr(int irq, void *dev_id) { struct acc_con_info *acc = (struct acc_con_info *)dev_id; ACC_CONDEV_DBG(""); cancel_delayed_work_sync(&acc->acc_id_dwork); schedule_delayed_work(&acc->acc_id_dwork, msecs_to_jiffies(DETECTION_DELAY_MS)); return IRQ_HANDLED; }
irqreturn_t acc_con_interrupt(int irq, void *ptr) { ACC_CONDEV_DBG(""); disable_irq_nosync(IRQ_ACCESSORY_INT); queue_work(acc_con_workqueue, &acc_con_work); return IRQ_HANDLED; }
static int acc_con_interrupt_init(struct acc_con_info *acc) { int ret; ACC_CONDEV_DBG(""); gpio_request(acc->pdata->accessory_irq_gpio, "accessory"); gpio_direction_input(acc->pdata->accessory_irq_gpio); tegra_gpio_enable(acc->pdata->accessory_irq_gpio); acc->accessory_irq = gpio_to_irq(acc->pdata->accessory_irq_gpio); ret = request_threaded_irq(acc->accessory_irq, NULL, acc_con_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "accessory_detect", acc); if (ret) { ACC_CONDEV_DBG("request_irq(accessory_irq) return : %d\n", ret); } return ret; }
static void acc_dwork_accessory_detect(struct work_struct *work) { struct acc_con_info *acc = container_of(work, struct acc_con_info, acc_id_dwork.work); int adc_val = 0; int acc_state = 0; acc_state = acc->pdata->get_acc_state(); if (acc_state) { ACC_CONDEV_DBG("Accessory detached"); acc_accessory_uevent(acc, false); } else { ACC_CONDEV_DBG("Accessory attached"); adc_val = acc_get_accessory_id(acc); acc_accessory_uevent(acc, adc_val); } }
void acc_ID_intr_handle(struct work_struct *_work) { //ACC_CONDEV_DBG(""); int acc_ID_val = 0, adc_val; acc_ID_val = gpio_get_value(GPIO_DOCK_INT); ACC_CONDEV_DBG("GPIO_DOCK_INT is %d",acc_ID_val); if(acc_ID_val!=ACC_STATE) { if(1==acc_ID_val) { ACC_CONDEV_DBG("Accessory detatched"); ACC_STATE = acc_ID_val; acc_notified(false); set_irq_type(IRQ_DOCK_INT, IRQ_TYPE_EDGE_FALLING); #ifdef CONFIG_USB_S3C_OTG_HOST if(intr_count++) s3c_usb_cable(USB_OTGHOST_DETACHED); #endif } else if(0==acc_ID_val) { msleep(420); //workaround for jack ACC_CONDEV_DBG("Accessory attached"); ACC_STATE = acc_ID_val; adc_val = connector_detect_change(); acc_notified(adc_val); set_irq_type(IRQ_DOCK_INT, IRQ_TYPE_EDGE_RISING); #ifdef CONFIG_USB_S3C_OTG_HOST // check USB OTG Host ADC range... if(adc_val > 2700 && adc_val < 2799) { s3c_usb_cable(USB_OTGHOST_ATTACHED); } #endif } } else { ACC_CONDEV_DBG("Ignored"); } enable_irq(IRQ_DOCK_INT); }
static int acc_con_suspend(struct platform_device *pdev, pm_message_t state) { struct acc_con_info *acc = platform_get_drvdata(pdev); ACC_CONDEV_DBG(""); disable_irq(acc->dock_irq); disable_irq(acc->accessory_irq); return 0; }
static int acc_ID_interrupt_init(struct acc_con_info *acc) { int ret; ACC_CONDEV_DBG(""); gpio_request(acc->pdata->dock_irq_gpio, "dock"); gpio_direction_input(acc->pdata->dock_irq_gpio); tegra_gpio_enable(acc->pdata->dock_irq_gpio); acc->dock_irq = gpio_to_irq(acc->pdata->dock_irq_gpio); ret = request_threaded_irq(acc->dock_irq, NULL, acc_ID_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "dock_detect", acc); if (ret) { ACC_CONDEV_DBG("request_irq(dock_irq) return : %d\n", ret); } enable_irq_wake(acc->dock_irq); return ret; }
static irqreturn_t acc_con_interrupt(int irq, void *ptr) { struct acc_con_info *acc = ptr; ACC_CONDEV_DBG(""); check_acc_dock(acc); return IRQ_HANDLED; }
static int acc_con_resume(struct platform_device *pdev) { struct acc_con_info *acc = platform_get_drvdata(pdev); ACC_CONDEV_DBG(""); enable_irq(acc->dock_irq); enable_irq(acc->accessory_irq); return 0; }
static int __init acc_con_init(void) { #if defined (CONFIG_TARGET_LOCALE_EUR) || defined (CONFIG_TARGET_LOCALE_HKTW) || defined (CONFIG_TARGET_LOCALE_HKTW_FET) || defined (CONFIG_TARGET_LOCALE_VZW) || defined (CONFIG_TARGET_LOCALE_USAGSM) if(HWREV < 0x8) return -1; #endif ACC_CONDEV_DBG(""); return platform_driver_register(&acc_con_driver); }
static int acc_con_suspend(struct platform_device *pdev, pm_message_t state) { struct acc_con_info *acc = platform_get_drvdata(pdev); ACC_CONDEV_DBG(""); #ifdef CONFIG_MHL_SII9234 if ((acc->current_dock == DOCK_DESK) || (acc->current_dock == DOCK_KEYBOARD)) MHD_HW_Off(); /*call MHL deinit */ #endif return 0; }
static int acc_con_resume(struct platform_device *pdev) { struct acc_con_info *acc = platform_get_drvdata(pdev); ACC_CONDEV_DBG(""); #ifdef CONFIG_MHL_SII9234 if ((acc->current_dock == DOCK_DESK) || (acc->current_dock == DOCK_KEYBOARD)) sii9234_tpi_init(); /* call MHL init */ #endif return 0; }
static int acc_init_dock_int(struct acc_con_info *acc) { int ret = 0; ACC_CONDEV_DBG(""); gpio_request(acc->pdata->accessory_irq_gpio, "accessory"); gpio_direction_input(acc->pdata->accessory_irq_gpio); acc->accessory_irq = gpio_to_irq(acc->pdata->accessory_irq_gpio); ret = request_threaded_irq(acc->accessory_irq, NULL, acc_dock_isr, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "accessory_detect", acc); if (ret) ACC_CONDEV_DBG("request_irq(accessory_irq) return : %d\n", ret); ret = enable_irq_wake(acc->accessory_irq); if (ret) ACC_CONDEV_DBG("enable_irq_wake(accessory_irq) return : %d\n", ret); return ret; }
static irqreturn_t acc_dock_isr(int irq, void *ptr) { struct acc_con_info *acc = ptr; ACC_CONDEV_DBG(""); acc_check_dock_detection(acc); return IRQ_HANDLED; }
static int acc_con_remove(struct platform_device *pdev) { ACC_CONDEV_DBG(""); #ifdef CONFIG_MHL_SII9234 i2c_del_driver(&SII9234A_i2c_driver); i2c_del_driver(&SII9234B_i2c_driver); i2c_del_driver(&SII9234C_i2c_driver); i2c_del_driver(&SII9234_i2c_driver); #endif return 0; }
static int acc_con_probe(struct platform_device *pdev) { struct acc_con_info *acc; struct acc_con_platform_data *pdata = pdev->dev.platform_data; int retval; ACC_CONDEV_DBG(""); if (pdata == NULL) { pr_err("%s: no pdata\n", __func__); return -ENODEV; } acc = kzalloc(sizeof(*acc), GFP_KERNEL); if (!acc) return -ENOMEM; acc->pdata = pdata; acc->current_dock = DOCK_NONE; acc->current_accessory = ACCESSORY_NONE; mutex_init(&acc->lock); retval = dev_set_drvdata(&pdev->dev, acc); if (retval < 0) goto err_sw_dock; acc->acc_dev = &pdev->dev; acc->dock_switch.name = "dock"; retval = switch_dev_register(&acc->dock_switch); if (retval < 0) goto err_sw_dock; acc->ear_jack_switch.name = "usb_audio"; retval = switch_dev_register(&acc->ear_jack_switch); if (retval < 0) goto err_sw_jack; wake_lock_init(&acc->wake_lock, WAKE_LOCK_SUSPEND, "30pin_con"); INIT_DELAYED_WORK(&acc->acc_dwork, acc_delay_work); schedule_delayed_work(&acc->acc_dwork, msecs_to_jiffies(24000)); INIT_DELAYED_WORK(&acc->acc_id_dwork, acc_id_delay_work); return 0; err_sw_jack: switch_dev_unregister(&acc->dock_switch); err_sw_dock: kfree(acc); return retval; }
irqreturn_t acc_ID_interrupt(int irq, void *ptr) { struct acc_con_info *acc = ptr; ACC_CONDEV_DBG(""); cancel_delayed_work_sync(&acc->acc_id_dwork); schedule_delayed_work(&acc->acc_id_dwork, msecs_to_jiffies(DETECTION_DELAY_MS)); return IRQ_HANDLED; }