int fsa9480_reset_ic(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = chip->client; /* Disable Interrupt Write 0x01 to 0x1B Register <= Reset IC Write 0x40 to 0x05 Register <= Mask interrupt1 Write 0x20 to 0x06 Register <= Mask interrupt2 Write 0x2F to 0x25 Register <= Mask interrupt charger Write 0x1E to 0x02 Register <= Initialize control register Enable Interrupt */ printk(KERN_WARNING "[FSA9480] %s. TSU8111 will be reset\n", __func__); fsa9480_detect_dev(usbsw, 2); disable_irq(client->irq); fsa9480_write_reg(client, 0x1B, 0x01); msleep(1); fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x40); fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x20); fsa9480_write_reg(client, FSA9480_REG_CHG_INT_MASK, 0xc0); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); enable_irq(client->irq); printk(KERN_WARNING "[FSA9480] %s. TSU8111 reset...Done\n", __func__); return 0; }
static int fsa9480_resume(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); /* device detection */ fsa9480_detect_dev(usbsw); return 0; }
static void fsa9480_usb_detect(struct work_struct *work) { struct fsa9480_usbsw *usbsw = container_of(work, struct fsa9480_usbsw, usb_work.work); usbsw->is_usb_ready = true; fsa9480_detect_dev(usbsw); }
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_usbsw *usbsw; int ret = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; chip = usbsw; i2c_set_clientdata(client, usbsw); ret = fsa9480_irq_init(usbsw); if (ret) goto fail1; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "failed to create fsa9480 attribute group\n"); goto fail2; } /* ADC Detect Time: 500ms */ fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6); if (chip->pdata->reset_cb) chip->pdata->reset_cb(); /* device detection */ fsa9480_detect_dev(usbsw, INT_ATTACH); pm_runtime_set_active(&client->dev); return 0; fail2: if (client->irq) free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_usbsw *usbsw; int ret = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; if (!usbsw->pdata) goto fail1; i2c_set_clientdata(client, usbsw); if (usbsw->pdata->cfg_gpio) usbsw->pdata->cfg_gpio(); fsa9480_reg_init(usbsw); ret = fsa9480_irq_init(usbsw); if (ret) goto fail1; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "failed to create fsa9480 attribute group\n"); goto fail2; } if (usbsw->pdata->reset_cb) usbsw->pdata->reset_cb(); /* device detection */ fsa9480_detect_dev(usbsw); return 0; fail2: if (client->irq) free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static int fsa9480_resume(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); int dev1, dev2; dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); /* device detection */ fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH); return 0; }
static irqreturn_t fsa9480_irq_handler(int irq, void *data) { struct fsa9480_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr; /* clear interrupt */ fsa9480_read_irq(client, &intr); /* device detection */ fsa9480_detect_dev(usbsw, intr); return IRQ_HANDLED; }
static irqreturn_t fsa9480_irq_thread(int irq, void *data) { struct fsa9480_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr; int max_events = 100; int events_seen = 0; /* * the fsa could have queued up a few events if we haven't processed * them promptly */ while (max_events-- > 0) { intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); if (intr < 0) dev_err(&client->dev, "%s: err %d\n", __func__, intr); else if (intr == 0) break; else if (intr > 0) events_seen++; } if (!max_events) dev_warn(&client->dev, "too many events. fsa hosed?\n"); if (!events_seen) { /* * interrupt was fired, but no status bits were set, * so device was reset. In this case, the registers were * reset to defaults so they need to be reinitialised. */ fsa9480_reg_init(usbsw); } /* * fsa may take some time to update the dev_type reg after reading * the int reg. */ usleep_range(200, 300); /* device detection */ fsa9480_detect_dev(usbsw); return IRQ_HANDLED; }
static irqreturn_t fsa9480_irq_thread(int irq, void *data) { struct fsa9480_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr; /* read and clear interrupt status bits */ intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); if (intr < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, intr); } else if (intr == 0) { /* interrupt was fired, but no status bits were set, so device was reset. In this case, the registers were reset to defaults so they need to be reinitialised. */ fsa9480_reg_init(usbsw); } /* device detection */ fsa9480_detect_dev(usbsw); return IRQ_HANDLED; }
static int fsa9480_resume(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); int dev1, dev2; if (device_may_wakeup(&client->dev) && client->irq) disable_irq_wake(client->irq); /* * Clear Pending interrupt. Note that detect_dev does what * the interrupt handler does. So, we don't miss pending and * we reenable interrupt if there is one. */ fsa9480_read_reg(client, FSA9480_REG_INT1); fsa9480_read_reg(client, FSA9480_REG_INT2); dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); /* device detection */ fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH); return 0; }
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_usbsw *usbsw; int ret = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; if (!usbsw->pdata) goto fail1; i2c_set_clientdata(client, usbsw); if (usbsw->pdata->cfg_gpio) usbsw->pdata->cfg_gpio(); fsa9480_reg_init(usbsw); ret = fsa9480_irq_init(usbsw); if (ret) goto fail1; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "failed to create fsa9480 attribute group\n"); goto fail2; } if (usbsw->pdata->reset_cb) usbsw->pdata->reset_cb(); /* device detection */ fsa9480_detect_dev(usbsw); #if defined(CONFIG_SAMSUNG_CAPTIVATE) || defined(CONFIG_SAMSUNG_FASCINATE) if (misc_register(&dockaudio_device)) printk("%s misc_register(%s) failed\n", __FUNCTION__, dockaudio_device.name); else { if (sysfs_create_group(&dockaudio_device.this_device->kobj, &dockaudio_group) < 0) dev_err("failed to create sysfs group for device %s\n", dockaudio_device.name); } #endif return 0; fail2: if (client->irq) free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw) { int device_type, ret; unsigned char val1, val2; struct fsa9480_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; #ifdef CONFIG_MACH_VICTORY adc_fsa = i2c_smbus_read_word_data(client, FSA9480_REG_ADC); if (adc_fsa < 0) dev_err(&client->dev, "%s: err %d\n", __func__, adc_fsa); if ( adc_fsa == WIMAX_CABLE_50K){ switch_set_state(&wimax_cable, USB_CABLE_50K); } else if (adc_fsa == WIMAX_CABLE_50K_DIS) { fsa9480_manual_switching(SWITCH_PORT_AUTO); switch_set_state(&wimax_cable, CABLE_DISCONNECT); } #endif device_type = i2c_smbus_read_word_data(client, FSA9480_REG_DEV_T1); if (device_type < 0) dev_err(&client->dev, "%s: err %d\n", __func__, device_type); val1 = device_type & 0xff; val2 = device_type >> 8; dev_info(&client->dev, "dev1: 0x%x, dev2: 0x%x\n", val1, val2); /* Attached */ if (val1 || val2) { /* USB */ #ifdef CONFIG_MACH_VICTORY if (val1 & DEV_T1_USB_MASK){ #else if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK ) { #endif if (pdata->usb_cb) pdata->usb_cb(FSA9480_ATTACHED); micro_usb_status = 1; #ifdef _SUPPORT_SAMSUNG_AUTOINSTALLER_ askon_gadget_disconnect(); if (!askon_status) UsbIndicator(1); #else UsbIndicator(1); #endif if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9480_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } #ifdef CONFIG_MACH_VICTORY } else if ( val2 & DEV_T2_USB_MASK ) { if (pdata->wimax_cb) pdata->wimax_cb(FSA9480_ATTACHED); switch_set_state(&wimax_cable, USB_CABLE_255K); #endif /* UART */ } else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) { if(val2 & DEV_T2_UART_MASK) MicroJigUARTOffStatus = 1; if (pdata->uart_cb) pdata->uart_cb(FSA9480_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9480_REG_MANSW1, SW_UART); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } if (val2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_ATTACHED); } /* CHARGER */ } else if (val1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9480_ATTACHED); /* JIG */ } else if (val2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_ATTACHED); /* Desk Dock */ } else if (val2 & DEV_AV) { if (pdata->deskdock_cb) pdata->deskdock_cb(FSA9480_ATTACHED); dock_status = 1; ret = i2c_smbus_write_byte_data(client, FSA9480_REG_MANSW1, SW_VAUDIO); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); /* Car Dock */ } else if (val2 & DEV_JIG_UART_ON) { if (pdata->cardock_cb) pdata->cardock_cb(FSA9480_ATTACHED); dock_status = 1; ret = i2c_smbus_write_byte_data(client, FSA9480_REG_MANSW1, SW_VAUDIO); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* Detached */ } else { /* USB */ #ifdef CONFIG_MACH_VICTORY if (usbsw->dev1 & DEV_T1_USB_MASK){ #else if (usbsw->dev1 & DEV_T1_USB_MASK || usbsw->dev2 & DEV_T2_USB_MASK) { #endif micro_usb_status = 0; UsbIndicator(0); if (pdata->usb_cb) pdata->usb_cb(FSA9480_DETACHED); #ifdef CONFIG_MACH_VICTORY /* USB JIG */ } else if (usbsw->dev2 & DEV_T2_USB_MASK) { if (pdata->wimax_cb) pdata->wimax_cb(FSA9480_DETACHED); switch_set_state(&wimax_cable, CABLE_DISCONNECT); #endif /* UART */ } else if (usbsw->dev1 & DEV_T1_UART_MASK || usbsw->dev2 & DEV_T2_UART_MASK) { if(usbsw->dev2 & DEV_T2_UART_MASK) MicroJigUARTOffStatus = 0; if (pdata->uart_cb) pdata->uart_cb(FSA9480_DETACHED); if (usbsw->dev2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_DETACHED); } /* CHARGER */ } else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9480_DETACHED); /* JIG */ } else if (usbsw->dev2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_DETACHED); /* Desk Dock */ } else if (usbsw->dev2 & DEV_AV) { if (pdata->deskdock_cb) pdata->deskdock_cb(FSA9480_DETACHED); dock_status = 0; ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); /* Car Dock */ } else if (usbsw->dev2 & DEV_JIG_UART_ON) { if (pdata->cardock_cb) pdata->cardock_cb(FSA9480_DETACHED); dock_status = 0; ret = i2c_smbus_read_byte_data(client, FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } } usbsw->dev1 = val1; usbsw->dev2 = val2; } static void fsa9480_reg_init(struct fsa9480_usbsw *usbsw) { struct i2c_client *client = usbsw->client; unsigned int ctrl = CON_MASK; int ret; #if defined (CONFIG_MACH_ATLAS) || defined (CONFIG_MACH_FORTE) /* mask interrupts (unmask attach/detach only) */ ret = i2c_smbus_write_word_data(client, FSA9480_REG_INT1_MASK, 0x1ffc); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); #elif CONFIG_MACH_VICTORY /* mask interrupts (unmask attach/detach only reserved attach only) */ ret = i2c_smbus_write_word_data(client, FSA9480_REG_INT1_MASK, 0x1dfc); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); #endif /* mask all car kit interrupts */ ret = i2c_smbus_write_word_data(client, FSA9480_REG_CK_INTMASK1, 0x07ff); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); /* ADC Detect Time: 500ms */ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_TIMING1, 0x6); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->mansw = i2c_smbus_read_byte_data(client, FSA9480_REG_MANSW1); if (usbsw->mansw < 0) dev_err(&client->dev, "%s: err %d\n", __func__, usbsw->mansw); if (usbsw->mansw) ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ctrl); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } static irqreturn_t fsa9480_irq_thread(int irq, void *data) { struct fsa9480_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr; /* read and clear interrupt status bits */ intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); if (intr < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, intr); } else if (intr == 0) { /* interrupt was fired, but no status bits were set, so device was reset. In this case, the registers were reset to defaults so they need to be reinitialised. */ fsa9480_reg_init(usbsw); } /* device detection */ fsa9480_detect_dev(usbsw); return IRQ_HANDLED; } static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) { struct i2c_client *client = usbsw->client; int ret; if (client->irq) { ret = request_threaded_irq(client->irq, NULL, fsa9480_irq_thread, IRQF_TRIGGER_FALLING, "fsa9480 micro USB", usbsw); if (ret) { dev_err(&client->dev, "failed to reqeust IRQ\n"); return ret; } ret = enable_irq_wake(client->irq); if (ret < 0) dev_err(&client->dev, "failed to enable wakeup src %d\n", ret); } return 0; } static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_usbsw *usbsw; int ret = 0; #ifdef CONFIG_MACH_FORTE s3c_gpio_cfgpin(GPIO_USB_SCL_28V, S3C_GPIO_OUTPUT); s3c_gpio_setpull(GPIO_USB_SCL_28V, S3C_GPIO_PULL_NONE); s3c_gpio_cfgpin(GPIO_USB_SDA_28V, S3C_GPIO_OUTPUT); s3c_gpio_setpull(GPIO_USB_SDA_28V, S3C_GPIO_PULL_NONE); #endif if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; if (!usbsw->pdata) goto fail1; i2c_set_clientdata(client, usbsw); local_usbsw = usbsw; // temp if (usbsw->pdata->cfg_gpio) usbsw->pdata->cfg_gpio(); fsa9480_reg_init(usbsw); ret = fsa9480_irq_init(usbsw); if (ret) goto fail1; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "failed to create fsa9480 attribute group\n"); goto fail2; } if (usbsw->pdata->reset_cb) usbsw->pdata->reset_cb(); indicator_dev.name = DRIVER_NAME; #if 1 indicator_dev.print_name = print_switch_name; indicator_dev.print_state = print_switch_state; #endif switch_dev_register(&indicator_dev); #if defined(CONFIG_MACH_VICTORY) ret = switch_dev_register(&wimax_cable); wimax_cable.print_state = wimax_cable_type; #endif /* device detection */ fsa9480_detect_dev(usbsw); // set fsa9480 init flag. if (usbsw->pdata->set_init_flag) usbsw->pdata->set_init_flag(); return 0; fail2: if (client->irq) free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; } static int __devexit fsa9480_remove(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); if (client->irq) { disable_irq_wake(client->irq); free_irq(client->irq, usbsw); } i2c_set_clientdata(client, NULL); sysfs_remove_group(&client->dev.kobj, &fsa9480_group); kfree(usbsw); return 0; } #ifdef CONFIG_PM static int fsa9480_suspend(struct i2c_client *client, pm_message_t mesg) { #ifdef CONFIG_MACH_VICTORY disable_irq(client->irq ); #endif return 0; } static int fsa9480_resume(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); #ifdef CONFIG_MACH_VICTORY enable_irq(client->irq); #endif /* device detection */ fsa9480_detect_dev(usbsw); return 0; } #else #define fsa9480_suspend NULL #define fsa9480_resume NULL #endif /* CONFIG_PM */ static const struct i2c_device_id fsa9480_id[] = { {"fsa9480", 0}, {} }; MODULE_DEVICE_TABLE(i2c, fsa9480_id); static struct i2c_driver fsa9480_i2c_driver = { .driver = { .name = "fsa9480", }, .probe = fsa9480_probe, .remove = __devexit_p(fsa9480_remove), .suspend = fsa9480_suspend, .resume = fsa9480_resume, .id_table = fsa9480_id, };
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { //struct regulator *regulator; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_platform_data *pdata = client->dev.platform_data; struct fsa9480_usbsw *usbsw; struct pm860x_vbus_info *vbus; #if 0 // TODO: struct pxa_vbus_info info; #endif unsigned int data; int ret = 0; u8 devID; u8 intr, intr2, intr_chg; u8 mansw1; unsigned int ctrl = CTRL_MASK; printk("[FSA9480] PROBE ......\n"); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -EIO; isProbe = 1; //add for AT Command //wake_lock_init(&JIGConnect_idle_wake, WAKE_LOCK_IDLE, "jig_connect_idle_wake"); wake_lock_init(&JIGConnect_suspend_wake, WAKE_LOCK_SUSPEND, "jig_connect_suspend_wake"); wake_lock_init(&mUSB_suspend_wake, WAKE_LOCK_SUSPEND, "mUSB_detect"); #ifdef CONFIG_KONA_PI_MGR ret=pi_mgr_qos_add_request(&qos_node, "fsa9480", PI_MGR_PI_ID_ARM_SUB_SYSTEM, PI_MGR_QOS_DEFAULT_VALUE); if (ret) { pr_err("%s: failed to add fsa9480 to qos\n",__func__); return -1; } #endif usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; chip = usbsw; i2c_set_clientdata(client, usbsw); #if defined (VBUS_DETECT) /* Init vbus for pxa(MARVELL) */ // chip->pdata = pm860x_pdata->vbus; vbus = kzalloc(sizeof(struct pm860x_vbus_info), GFP_KERNEL); if (!vbus) { ret = -ENOMEM; goto out_mem; } dev_set_drvdata(&client->dev, vbus); vbus->res = kzalloc(sizeof(struct resource), GFP_KERNEL); if (!vbus->res) { ret = -ENOMEM; goto out_mem2; } vbus->res->start = pdata->vbus->reg_base; vbus->res->end = pdata ->vbus->reg_end; memset(&info,0,sizeof(struct pxa_vbus_info)); info.dev = &client->dev; info.res = vbus->res; pxa_vbus_init(&info); data = VBUS_A_VALID | VBUS_A_SESSION_VALID | VBUS_B_SESSION_VALID | VBUS_B_SESSION_END | VBUS_ID; pxa_unmask_vbus(data); #endif #if defined(CONFIG_SPA) spa_external_event = spa_get_external_event_handler(); #elif defined(CONFIG_BATTERY_D2083) ret = d2083_register_enable_charge(TSU8111_Charger_Enable); if(ret < 0) { pr_err("%s. fail to register enable charge function\n", __func__); goto out_charger_enable; } ret = d2083_register_enable_back_charge(TSU8111_Charger_BackCHG_Enable); if(ret < 0) { pr_err("%s. fail to register enable charge function\n", __func__); goto out_charger_enable; } ret = d2083_register_disable_charge(TSU8111_Charger_Disable); if(ret < 0) { pr_err("%s. fail to register disable charge function\n", __func__); goto out_charger_disable; } spa_external_event = d2083_get_external_event_handler(); #endif /* clear interrupt */ fsa9480_read_reg(client, FSA9480_REG_INT1, &intr); fsa9480_read_reg(client, FSA9480_REG_DEVID, &devID); if(devID==0x0a || devID==0x5A) muic_type=muicTypeTI6111; else if(devID==0x00) muic_type=muicTypeFSA880; else muic_type=muicTypeFSA; if(muic_type==muicTypeFSA880) { intr &= 0xffff; /* set control register */ fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x04); } else if(muic_type==muicTypeTI6111) { intr &= 0xffff; /* clear interrupt */ fsa9480_read_reg(client, FSA9480_REG_INT2, &intr2); fsa9480_read_reg(client, FSA9480_REG_CHG_INT, &intr_chg); /* unmask interrupt (attach/detach only) */ ret = fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x00); if (ret < 0) return ret; #if 0/*FSA9480's Interrupt Mask init setting*/ //ret = fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x00); #endif /*TI USB : not to get Connect Interrupt : no more double interrupt*/ ret = fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x40); if (ret < 0) return ret; ret = fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x20); if (ret < 0) return ret; ret = fsa9480_write_reg(client, FSA9480_REG_CHG_INT_MASK, 0xc0); if (ret < 0) return ret; fsa9480_read_reg(client, FSA9480_REG_MANSW1, &mansw1); usbsw->mansw = mansw1; ctrl &= ~INT_MASK; /* Unmask Interrupt */ if (usbsw->mansw) ctrl &= ~MANUAL_SWITCH; /* Manual Switching Mode */ fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); } else printk("[FSA9480] Error!!!! No Type. Check dev ID(0x01 addr) ......\n"); ret = fsa9480_irq_init(usbsw); if (ret) goto fsa9480_probe_fail; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "[FSA9480] Creating fsa9480 attribute group failed"); goto fsa9480_probe_fail2; } /* device detection */ fsa9480_detect_dev(usbsw, 1); isProbe = 0; tsu8111_check_ovp(); /*reset UIC*/ if(muic_type==muicTypeFSA880) fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x04); else { fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); /*set timing1 to 100ms*/ // fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x1); } #ifdef CONFIG_KONA_PI_MGR //ret=pi_mgr_qos_request_update(&qos_node, 0); //if (ret) //{ // pr_err("%s: failed to request update qos_node\n",__func__); //} #endif printk("[FSA9480] PROBE Done.\n"); return 0; out_mem: return ret; #if defined(CONFIG_BATTERY_D2083) out_charger_enable: out_charger_disable: #endif /* CONFIG_BATTERY_D2083 */ out_mem2: kfree(vbus); fsa9480_probe_fail2: if (client->irq) free_irq(client->irq, NULL); fsa9480_probe_fail: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static void fsa9480_work_cb(struct work_struct *work) { u8 intr, intr2, intr3; struct fsa9480_usbsw *usbsw = container_of(work, struct fsa9480_usbsw, work); struct i2c_client *client = usbsw->client; wake_lock_timeout(&mUSB_suspend_wake,1*HZ); /* clear interrupt */ if(muic_type==muicTypeTI6111) { msleep(200); fsa9480_read_reg(client, FSA9480_REG_INT1, &intr); fsa9480_read_reg(client, FSA9480_REG_INT2, &intr2); fsa9480_read_reg(client, FSA9480_REG_CHG_INT, &intr3); printk("[FSA9480] %s: intr=0x%x, intr2 = 0x%X, chg_intr=0x%x \n",__func__,intr,intr2, intr3); } else { fsa9480_read_reg(client, FSA9480_REG_INT1, &intr); fsa9480_read_reg(client, FSA9480_REG_INT2, &intr2); printk("[FSA9480] %s: intr=0x%x, intr2=0x%x \n",__func__,intr,intr2); } if(intr3 & CH_DONE) //EOC disable charger // Luke { //msleep(500); // Test only //fsa9480_read_reg(client, FSA9480_REG_DEV_T1, &val1); //if(val1&=DEV_VBUS) // Check if VBUS is valid //Luke //{ #if defined(CONFIG_BATTERY_D2083) if(spa_external_event) { pr_info("%s. Send D2083_EVENT_CHARGE_FULL event\n", __func__); spa_external_event(D2083_CATEGORY_BATTERY, D2083_EVENT_CHARGE_FULL); } //} #endif } intr &= 0xffff; /* device detection */ fsa9480_detect_dev(usbsw, intr); if((intr== 0x00) && (intr3 == 0)) { printk("[FSA9480] (intr== 0x00) in work_cb !!!!!\n"); fsa9480_read_adc_value(); #if 0 // TODO: if(muic_type==muicTypeTI6111) TI_SWreset(usbsw); #endif return; } if(!(intr3 & CH_DONE)) tsu8111_check_ovp(); if( intr==0x03) // INT error case fsa9480_reset_ic(); }