static int smb347_irq_init(struct smb347_charger *smb) { const struct smb347_charger_platform_data *pdata = smb->pdata; int ret, irq = gpio_to_irq(pdata->irq_gpio); ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, smb->client->name); if (ret < 0) goto fail; ret = request_threaded_irq(irq, NULL, smb347_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, smb->client->name, smb); if (ret < 0) goto fail_gpio; ret = smb347_set_writable(smb, true); if (ret < 0) goto fail_irq; /* * Configure the STAT output to be suitable for interrupts: disable * all other output (except interrupts) and make it active low. */ ret = smb347_read(smb, CFG_STAT); if (ret < 0) goto fail_readonly; ret &= ~CFG_STAT_ACTIVE_HIGH; ret |= CFG_STAT_DISABLED; ret = smb347_write(smb, CFG_STAT, ret); if (ret < 0) goto fail_readonly; ret = smb347_irq_enable(smb); if (ret < 0) goto fail_readonly; smb347_set_writable(smb, false); smb->client->irq = irq; return 0; fail_readonly: smb347_set_writable(smb, false); fail_irq: free_irq(irq, smb); fail_gpio: gpio_free(pdata->irq_gpio); fail: smb->client->irq = 0; return ret; }
static int smb347_irq_init(struct smb347_charger *smb) { const struct smb347_charger_platform_data *pdata = smb->pdata; int ret, irq = gpio_to_irq(pdata->irq_gpio); ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, smb->client->name); if (ret < 0) goto fail; ret = request_threaded_irq(irq, NULL, smb347_interrupt, IRQF_TRIGGER_FALLING, smb->client->name, smb); if (ret < 0) goto fail_gpio; ret = smb347_set_writable(smb, true); if (ret < 0) goto fail_irq; ret = smb347_read(smb, CFG_STAT); if (ret < 0) goto fail_readonly; ret &= ~CFG_STAT_ACTIVE_HIGH; ret |= CFG_STAT_DISABLED; ret = smb347_write(smb, CFG_STAT, ret); if (ret < 0) goto fail_readonly; ret = smb347_irq_enable(smb); if (ret < 0) goto fail_readonly; smb347_set_writable(smb, false); smb->client->irq = irq; return 0; fail_readonly: smb347_set_writable(smb, false); fail_irq: free_irq(irq, smb); fail_gpio: gpio_free(pdata->irq_gpio); fail: smb->client->irq = 0; return ret; }
static int smb347_hw_init(struct smb347_charger *smb) { int ret; ret = smb347_set_writable(smb, true); if (ret < 0) return ret; /* * Program the platform specific configuration values to the device * first. */ ret = smb347_set_charge_current(smb); if (ret < 0) goto fail; ret = smb347_set_current_limits(smb); if (ret < 0) goto fail; ret = smb347_set_voltage_limits(smb); if (ret < 0) goto fail; // HACK for Manta pre-alpha 0.2, TH_BATTERY not connected properly #if 0 // HACK ret = smb347_set_temp_limits(smb); if (ret < 0) goto fail; #endif // HACK /* If USB charging is disabled we put the USB in suspend mode */ if (!smb->pdata->use_usb) { ret = smb347_read(smb, CMD_A); if (ret < 0) goto fail; ret |= CMD_A_SUSPEND_ENABLED; ret = smb347_write(smb, CMD_A, ret); if (ret < 0) goto fail; } ret = smb347_read(smb, CFG_OTHER); if (ret < 0) goto fail; /* * If configured by platform data, we enable hardware Auto-OTG * support for driving VBUS. Otherwise we disable it. */ ret &= ~CFG_OTHER_RID_MASK; if (smb->pdata->use_usb_otg) ret |= CFG_OTHER_RID_ENABLED_AUTO_OTG; ret = smb347_write(smb, CFG_OTHER, ret); if (ret < 0) goto fail; ret = smb347_read(smb, CFG_PIN); if (ret < 0) goto fail; /* * Make the charging functionality controllable by a write to the * command register unless pin control is specified in the platform * data. */ ret &= ~(CFG_PIN_EN_CTRL_MASK | CFG_PIN_USB_MODE_CTRL); switch (smb->pdata->enable_control) { case SMB347_CHG_ENABLE_SW: /* Do nothing, 0 means i2c control */ break; case SMB347_CHG_ENABLE_PIN_ACTIVE_LOW: ret |= CFG_PIN_EN_CTRL_ACTIVE_LOW; break; case SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH: ret |= CFG_PIN_EN_CTRL_ACTIVE_HIGH; break; } if (smb->pdata->usb_mode_pin_ctrl) ret |= CFG_PIN_USB_MODE_CTRL; /* Disable Automatic Power Source Detection (APSD) interrupt. */ ret &= ~CFG_PIN_EN_APSD_IRQ; ret = smb347_write(smb, CFG_PIN, ret); if (ret < 0) goto fail; ret = smb347_update_status(smb); if (ret < 0) goto fail; ret = smb347_update_online(smb); if (smb->pdata->irq_gpio >= 0) { /* * Configure the STAT output to be suitable for interrupts: * disable all other output (except interrupts) and make it * active low. */ ret = smb347_read(smb, CFG_STAT); if (ret < 0) goto fail; ret &= ~CFG_STAT_ACTIVE_HIGH; ret |= CFG_STAT_DISABLED; ret = smb347_write(smb, CFG_STAT, ret); if (ret < 0) goto fail; ret = smb347_irq_enable(smb); if (ret < 0) goto fail; } fail: smb347_set_writable(smb, false); return ret; }