static void initial_connection_check(struct acc_con_info *acc) { int dock_state; int otg_state; int jig_state; s16 adc_val; /* checks dock connectivity before registers dock irq */ dock_state = gpio_get_value(acc->pdata->accessory_irq_gpio); if (!dock_state) acc_dock_check(acc, true); /* checks otg connectivity before registers otg irq */ otg_state = gpio_get_value(acc->pdata->dock_irq_gpio); if (!otg_state) { wake_lock(&acc->wake_lock); msleep(420); /* workaround for jack */ connector_detect_change(acc, &adc_val); acc_notified(acc, adc_val); wake_unlock(&acc->wake_lock); } /* checks jig connectivity before registers jig irq */ jig_state = gpio_get_value(acc->pdata->jig_on_gpio); if (jig_state) _detected(acc, P30_JIG, 1); }
irqreturn_t acc_ID_interrupt(int irq, void *ptr) { struct acc_con_info *acc = ptr; int acc_ID_val, adc_val; static int post_state = -1; ACC_CONDEV_DBG(""); acc_ID_val = gpio_get_value(acc->pdata->dock_irq_gpio); ACC_CONDEV_DBG("IRQ_DOCK_GPIO is %d", acc_ID_val); if (acc_ID_val == 1) { if (post_state != 1) { post_state = 1; ACC_CONDEV_DBG("Accessory detached"); // switch_set_state(&acc->ear_jack_switch, 0); acc_notified(acc, false); set_irq_type(irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT); } else ACC_CONDEV_DBG("[WARNING] duplication detache --> ignore"); } else if (acc_ID_val == 0) { if (post_state != 0) { wake_lock(&acc->wake_lock); post_state = 0; msleep(420); /* workaround for jack */ ACC_CONDEV_DBG("Accessory attached"); // switch_set_state(&acc->ear_jack_switch, 1); adc_val = connector_detect_change(); acc_notified(acc, adc_val); set_irq_type(irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT); wake_unlock(&acc->wake_lock); } else { adc_val = connector_detect_change(); ACC_CONDEV_DBG("[WARNING] duplication attache (adc = %d) --> ignore", adc_val); } } return IRQ_HANDLED; }
static irqreturn_t acc_id_interrupt(int irq, void *ptr) { struct acc_con_info *acc = ptr; int acc_id_val; #ifndef CONFIG_SAMSUNG_Y_CABLE s16 adc_val; #endif int delay = 10; static int post_state = -1; acc_id_val = gpio_get_value(acc->pdata->dock_irq_gpio); pr_info("accessorry_id irq handler: dock_irq gpio val = %d\n", acc_id_val); if (acc_id_val == post_state) { pr_warning("30pin: duplicated otg connection event,ignore(%d).", acc_id_val); return IRQ_HANDLED; } while (delay > 0) { if (acc_id_val != gpio_get_value(acc->pdata->dock_irq_gpio)) return IRQ_HANDLED; usleep_range(10000, 11000); delay--; } if (acc_id_val) { pr_info("Accessory detached"); acc_notified(acc, false); #ifdef CONFIG_SAMSUNG_Y_CABLE adc_val = 0; /*we are using this value for next detection as well, we need it to be updated at all times*/ #endif } else { wake_lock(&acc->wake_lock); msleep(420); /* workaround for jack */ connector_detect_change(acc, &adc_val); pr_info("Accessory attached, adc=%d\n", adc_val); acc_notified(acc, adc_val); wake_unlock(&acc->wake_lock); } post_state = acc_id_val; return IRQ_HANDLED; }
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 acc_ID_val, adc_val; static int post_state = -1; ACC_CONDEV_DBG(""); acc_ID_val = gpio_get_value(acc->pdata->dock_irq_gpio); ACC_CONDEV_DBG("IRQ_DOCK_GPIO is %d", acc_ID_val); if (acc_ID_val == 1) { if (post_state != 1) { post_state = 1; ACC_CONDEV_DBG("Accessory detached"); acc_notified(acc, false); } else ACC_CONDEV_DBG("Duplication detach"); } else if (acc_ID_val == 0) { if (post_state != 0) { wake_lock(&acc->wake_lock); post_state = 0; msleep(420); /* workaround for jack */ ACC_CONDEV_DBG("Accessory attached"); adc_val = connector_detect_change(); acc_notified(acc, adc_val); wake_unlock(&acc->wake_lock); } else { adc_val = connector_detect_change(); ACC_CONDEV_DBG("Duplication attach (adc = %d)", adc_val); } } }
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); }
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); }