/** * Store the test_id_store attribure. */ STATIC ssize_t test_id_store(struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) { struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); struct hiusb_info *hiusb_info = lm_dev->hiusb_info; uint32_t val = simple_strtoul(buf, NULL, 16); if (hiusb_info->insert_irq == 0 || hiusb_info->draw_irq == 0) { dev_info(&lm_dev->dev, "No insert/draw irq.\n"); return 0; } if (val == 0) { hiusb_id_changed(ID_RISE_EVENT); msleep(3000); hiusb_id_changed(ID_FALL_EVENT); } else { hiusb_vbus_intr(hiusb_info->draw_irq, lm_dev); msleep(3000); hiusb_vbus_intr(hiusb_info->insert_irq, lm_dev); } return count; }
int switch_usb(void) { int ret = -1; ret = __switch_usb(); hiusb_id_changed(ID_FALL_EVENT); return ret; }
static void fsa9685_intb_work(struct work_struct *work) { int gpio_value = 0; int reg02, reg03, reg05, reg08, reg09, reg10; int ret = -1; static int otg_attach = 0; int invalid_status=1; static int invalid_times=0; static int last_status = STATUS_FSA9685_UNINIT; if (down_interruptible(&g_intb_sema)) { printk(KERN_ERR "%s %s down_interruptible error\n", __func__, FSA9685_ERROR_TAG); return; } printk(KERN_INFO "%s ++\n", __func__); gpio_value = gpio_get_value(gpio); reg03 = fsa9685_read_reg(FSA9685_REG_INTERRUPT); printk(KERN_INFO "%s reg03=0x%x\n", __func__,reg03); if(unlikely(reg03<0)){ invalid_status=0; printk(KERN_ERR "%s %s read intr error\n", __func__, FSA9685_ERROR_TAG); }else if(unlikely(reg03==0)){ invalid_status=0; printk(KERN_ERR "%s no intr\n", __func__); }else { if(gpio_value==1){ printk(KERN_ERR "%s %s intb high when interrupt\n", __func__, FSA9685_ERROR_TAG); } if ( (reg03 & FSA9685_DETACH) && (last_status == STATUS_FSA9685_ATTACH) ) { printk(KERN_INFO "%s: FSA9685_DETACH\n", __func__); reg03 &= ~FSA9685_DETACH; last_status = STATUS_FSA9685_DETACH; invalid_status = 0; /* check control register, if manual switch, reset to auto switch */ reg02 = fsa9685_read_reg(FSA9685_REG_CONTROL); reg09 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_2); printk(KERN_INFO "%s reg02=0x%x\n", __func__, reg02); if ( 0 == (reg02 & FSA9685_MANUAL_SW) ) { reg02 |= FSA9685_MANUAL_SW; ret = fsa9685_write_reg(FSA9685_REG_CONTROL, reg02); if ( ret < 0 ){ printk(KERN_ERR "%s %s write reg02 fail\n", __func__, FSA9685_ERROR_TAG); goto OUT; } } if (reg09 & FSA9685_JIG_UART ) { printk(KERN_INFO "%s: FSA9685_JIG_UART\n", __func__); } if (otg_attach==1) { hiusb_id_changed(ID_RISE_EVENT); otg_attach=0; } } if ( reg03 & FSA9685_ATTACH ) { last_status = STATUS_FSA9685_ATTACH; reg03 &= ~FSA9685_ATTACH; printk(KERN_INFO "%s: FSA9685_ATTACH\n", __func__); reg08 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_1); reg09 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_2); reg10 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_3); printk(KERN_INFO "%s reg08=0x%x, reg09=0x%x, reg10=0x%x\n", __func__, reg08, reg09, reg10); if (reg08 & FSA9685_FC_USB_DETECTED ) { printk(KERN_INFO "%s: FSA9685_FC_USB_DETECTED\n", __func__); } if (reg08 & FSA9685_FC_RF_DETECTED ) { printk(KERN_INFO "%s: FSA9685_FC_RF_DETECTED\n", __func__); } if (reg08 & FSA9685_USB_DETECTED ) { printk(KERN_INFO "%s: FSA9685_USB_DETECTED\n", __func__); invalid_status = 0; if (FSA9685_USB1 == get_swstate_value()) { switch_usb2_access_through_ap(); printk(KERN_INFO "%s: fsa9685 switch to USB2 by setvalue\n", __func__); } } if (reg08 & FSA9685_UART_DETECTED ) { printk(KERN_INFO "%s: FSA9685_UART_DETECTED\n", __func__); } if (reg08 & FSA9685_MHL_DETECTED ) { printk(KERN_INFO "%s: FSA9685_MHL_DETECTED\n", __func__); invalid_status = 0; } if (reg08 & FSA9685_CDP_DETECTED ) { printk(KERN_INFO "%s: FSA9685_CDP_DETECTED\n", __func__); invalid_status = 0; } if (reg08 & FSA9685_DCP_DETECTED ) { printk(KERN_INFO "%s: FSA9685_DCP_DETECTED\n", __func__); invalid_status = 0; } if (reg08 & FSA9685_USBOTG_DETECTED ) { printk(KERN_INFO "%s: FSA9685_USBOTG_DETECTED and wait for 30ms\n", __func__); invalid_status = 0; msleep(30); otg_attach = 1; hiusb_id_changed(ID_FALL_EVENT); } if (reg09 & FSA9685_JIG_UART ) { printk(KERN_INFO "%s: FSA9685_JIG_UART\n", __func__); invalid_status = 0; } if (reg10 & FSA9685_CUSTOMER_ACCESSORY) { if ( reg03 & FSA9685_VBUS_CHANGE) { invalid_status = 0; fsa9685_manual_sw(FSA9685_USB1); } printk(KERN_INFO "%s: FSA9685_CUSTOMER_ACCESORY mode = %d\n",__func__,reg10); } } if ( reg03 & FSA9685_DETACH ) { printk(KERN_INFO "%s: FSA9685_DETACH\n", __func__); reg03 &= ~FSA9685_DETACH; last_status = STATUS_FSA9685_DETACH; invalid_status = 0; /* check control register, if manual switch, reset to auto switch */ reg02 = fsa9685_read_reg(FSA9685_REG_CONTROL); reg09 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_2); printk(KERN_INFO "%s reg02=0x%x\n", __func__, reg02); if ( 0 == (reg02 & FSA9685_MANUAL_SW) ) { reg02 |= FSA9685_MANUAL_SW; ret = fsa9685_write_reg(FSA9685_REG_CONTROL, reg02); if ( ret < 0 ){ printk(KERN_ERR "%s %s write reg02 fail\n", __func__, FSA9685_ERROR_TAG); goto OUT; } } if (reg09 & FSA9685_JIG_UART ) { printk(KERN_INFO "%s: FSA9685_JIG_UART\n", __func__); } if (otg_attach==1) { hiusb_id_changed(ID_RISE_EVENT); otg_attach=0; } } if ( reg03 & FSA9685_VBUS_CHANGE) { invalid_status = 0; printk(KERN_INFO "%s: FSA9685_VBUS_CHANGE\n", __func__); } if ( reg03 & FSA9685_RESERVED_ATTACH ) { if ( reg03 & FSA9685_VBUS_CHANGE) { invalid_status = 0; fsa9685_manual_sw(FSA9685_USB1); } printk(KERN_INFO "%s: FSA9685_RESERVED_ATTACH", __func__); } if ( reg03 & FSA9685_ADC_CHANGE) { reg05 = fsa9685_read_reg(FSA9685_REG_ADC); printk(KERN_INFO "%s: FSA9685_ADC_CHANGE. reg05= 0x%x\n", __func__, reg05); /* do user specific handle */ } } OUT: #ifdef FSA9685_HAVE_RESET if(invalid_status && invalid_times<3){ invalid_times++; printk(KERN_ERR "%s %s invalid time:%d reset fsa9685 work\n", __func__, FSA9685_ERROR_TAG, invalid_times); fsa9685_reset_work(&g_reset_work); }else{ invalid_times=0; } #endif up(&g_intb_sema); printk(KERN_INFO "%s --\n", __func__); return; }