static int pm860x_charger_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_charger_info *info; int ret; int count; int i; int j; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; count = pdev->num_resources; for (i = 0, j = 0; i < count; i++) { info->irq[j] = platform_get_irq(pdev, i); if (info->irq[j] < 0) continue; j++; } info->irq_nums = j; info->chip = chip; info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : chip->client; if (!info->i2c_8606) { dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n"); ret = -EINVAL; goto out; } info->dev = &pdev->dev; /* set init value for the case we are not using battery */ set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_OVP_LOW); mutex_init(&info->lock); platform_set_drvdata(pdev, info); info->usb.name = "usb"; info->usb.type = POWER_SUPPLY_TYPE_USB; info->usb.supplied_to = pm860x_supplied_to; info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); info->usb.properties = pm860x_usb_props; info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props); info->usb.get_property = pm860x_usb_get_prop; ret = power_supply_register(&pdev->dev, &info->usb); if (ret) goto out; pm860x_init_charger(info); for (i = 0; i < ARRAY_SIZE(info->irq); i++) { ret = request_threaded_irq(info->irq[i], NULL, pm860x_irq_descs[i].handler, IRQF_ONESHOT, pm860x_irq_descs[i].name, info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[i], ret); goto out_irq; } } return 0; out_irq: while (--i >= 0) free_irq(info->irq[i], info); out: return ret; }
static __devinit int pm860x_charger_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_platform_data *pdata = chip->dev->platform_data; struct pm860x_charger_info *info; int ret, i, j, count; info = kzalloc(sizeof(struct pm860x_charger_info), GFP_KERNEL); if (!info) return -ENOMEM; ret = device_create_file(&pdev->dev, &dev_attr_control); if (ret < 0) goto out; count = pdev->num_resources; for (i = 0, j = 0; i < count; i++) { info->irq[j] = platform_get_irq(pdev, i); if (info->irq[j] < 0) continue; j++; } ginfo = info; info->irq_nums = j; info->batdet = pdata->batt_det; pr_info( \ "charger:pm860x_charger_probe:info->batdet=[%d]\n", info->batdet); info->chip = chip; info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : chip->client; if (!info->i2c_8606) { dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n"); ret = -EINVAL; goto out_dev; } info->dev = &pdev->dev; #ifdef CONFIG_ALTERNATE_CHARGER pm860x_registerChargerEventsCb(pm860x_default_chg_handler,0); pm860x_registerChargerEventsCb(pm860x_default_chg_handler,1); pm860x_registerChargerEventsCb(pm860x_default_chg_handler,2); pm860x_registerChargerEventsCb(pm860x_default_chg_handler,3); pm860x_registerChargerEventsCb(pm860x_default_chg_handler,4); //pm860x_registerChargerEventsCb(pm860x_default_chg_handler,5); pm860x_registerChargerEventsCb(m_spa_voltThresholdEvent,5); pm860x_registerChargerEventsCb(pm860x_default_chg_handler,6); pm860x_register_control_cb_func(spa_Charger_Ctrl); #else ChargerEventsCb[0] = pm860x_charger_handler; ChargerEventsCb[1] = pm860x_done_handler; ChargerEventsCb[2] = pm860x_exception_handler; ChargerEventsCb[3] = pm860x_exception_handler; ChargerEventsCb[4] = pm860x_temp_handler; ChargerEventsCb[5] = pm860x_vbattery_handler; ChargerEventsCb[6] = pm860x_vchg_handler; #endif /* set init value for the case we are not using battery*/ set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_OVP_LOW); #if !defined(CONFIG_USB_VBUS_88PM860X) if (ChargerEventsCb[0]) { ret = request_threaded_irq(info->irq[0], NULL, ChargerEventsCb[0], IRQF_ONESHOT, "usb supply detect", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[0], ret); goto out_dev; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 0); #endif if (ChargerEventsCb[1]) { ret = request_threaded_irq(info->irq[1], NULL, ChargerEventsCb[1], IRQF_ONESHOT, "charge done", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[1], ret); goto out_irq1; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 1); if (ChargerEventsCb[2]) { ret = request_threaded_irq(info->irq[2], NULL, ChargerEventsCb[2], IRQF_ONESHOT, "charge timeout", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[2], ret); goto out_irq2; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 2); if (ChargerEventsCb[3]) { ret = request_threaded_irq(info->irq[3], NULL, ChargerEventsCb[3], IRQF_ONESHOT, "charge fault", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[3], ret); goto out_irq3; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 3); if (ChargerEventsCb[4]) { ret = request_threaded_irq(info->irq[4], NULL, ChargerEventsCb[4], IRQF_ONESHOT, "temperature", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[4], ret); goto out_irq4; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 4); if (ChargerEventsCb[5]) { ret = request_threaded_irq(info->irq[5], NULL, ChargerEventsCb[5], IRQF_ONESHOT, "vbatt", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[5], ret); goto out_irq5; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 5); if (ChargerEventsCb[6]) { ret = request_threaded_irq(info->irq[6], NULL, ChargerEventsCb[6], IRQF_ONESHOT, "vchg", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[6], ret); goto out_irq6; } if (info->irq_nums <= 6) { dev_err(chip->dev, "IRQ numbers aren't matched\n"); goto out_nums; } } else pr_info( \ "pm860x_charger_probe:no callback for charger event[%d]\n", 6); mutex_init(&info->lock); platform_set_drvdata(pdev, info); #ifndef CONFIG_ALTERNATE_CHARGER info->usb.name = "usb"; info->usb.type = POWER_SUPPLY_TYPE_USB; info->usb.supplied_to = pm860x_supplied_to; info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); info->usb.properties = pm860x_usb_props; info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props); info->usb.get_property = pm860x_usb_get_prop; ret = power_supply_register(&pdev->dev, &info->usb); if (ret) goto out_nums; info->ac.name = "ac"; info->ac.type = POWER_SUPPLY_TYPE_MAINS; info->ac.supplied_to = pm860x_supplied_to; info->ac.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); info->ac.properties = pm860x_ac_props; info->ac.num_properties = ARRAY_SIZE(pm860x_ac_props); info->ac.get_property = pm860x_ac_get_prop; ret = power_supply_register(&pdev->dev, &info->ac); if (ret) goto out_nums; pm860x_init_charger(info); #endif INIT_WORK(&info->vbus_work, pm860x_vbus_work); device_init_wakeup(&pdev->dev, 1); #ifdef CONFIG_PROC_FS create_pm860x_power_proc_file(); #endif return 0; out_nums: free_irq(info->irq[6], info); out_irq6: free_irq(info->irq[5], info); out_irq5: free_irq(info->irq[4], info); out_irq4: free_irq(info->irq[3], info); out_irq3: free_irq(info->irq[2], info); out_irq2: free_irq(info->irq[1], info); out_irq1: #if !defined(CONFIG_USB_VBUS_88PM860X) free_irq(info->irq[0], info); #endif out_dev: device_remove_file(&pdev->dev, &dev_attr_control); out: kfree(info); return ret; }