static int da9150_charger_probe()

in supply/da9150-charger.c [514:643]


static int da9150_charger_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct da9150 *da9150 = dev_get_drvdata(dev->parent);
	struct da9150_charger *charger;
	u8 reg;
	int ret;

	charger = devm_kzalloc(dev, sizeof(struct da9150_charger), GFP_KERNEL);
	if (!charger)
		return -ENOMEM;

	platform_set_drvdata(pdev, charger);
	charger->da9150 = da9150;
	charger->dev = dev;

	/* Acquire ADC channels */
	charger->ibus_chan = iio_channel_get(dev, "CHAN_IBUS");
	if (IS_ERR(charger->ibus_chan)) {
		ret = PTR_ERR(charger->ibus_chan);
		goto ibus_chan_fail;
	}

	charger->vbus_chan = iio_channel_get(dev, "CHAN_VBUS");
	if (IS_ERR(charger->vbus_chan)) {
		ret = PTR_ERR(charger->vbus_chan);
		goto vbus_chan_fail;
	}

	charger->tjunc_chan = iio_channel_get(dev, "CHAN_TJUNC");
	if (IS_ERR(charger->tjunc_chan)) {
		ret = PTR_ERR(charger->tjunc_chan);
		goto tjunc_chan_fail;
	}

	charger->vbat_chan = iio_channel_get(dev, "CHAN_VBAT");
	if (IS_ERR(charger->vbat_chan)) {
		ret = PTR_ERR(charger->vbat_chan);
		goto vbat_chan_fail;
	}

	/* Register power supplies */
	charger->usb = power_supply_register(dev, &usb_desc, NULL);
	if (IS_ERR(charger->usb)) {
		ret = PTR_ERR(charger->usb);
		goto usb_fail;
	}

	charger->battery = power_supply_register(dev, &battery_desc, NULL);
	if (IS_ERR(charger->battery)) {
		ret = PTR_ERR(charger->battery);
		goto battery_fail;
	}

	/* Get initial online supply */
	reg = da9150_reg_read(da9150, DA9150_STATUS_H);

	switch (reg & DA9150_VBUS_STAT_MASK) {
	case DA9150_VBUS_STAT_OFF:
	case DA9150_VBUS_STAT_WAIT:
		charger->supply_online = charger->battery;
		break;
	case DA9150_VBUS_STAT_CHG:
		charger->supply_online = charger->usb;
		break;
	default:
		dev_warn(dev, "Unknown VBUS state - reg = 0x%x\n", reg);
		charger->supply_online = NULL;
		break;
	}

	/* Setup OTG reporting & configuration */
	charger->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
	if (!IS_ERR_OR_NULL(charger->usb_phy)) {
		INIT_WORK(&charger->otg_work, da9150_charger_otg_work);
		charger->otg_nb.notifier_call = da9150_charger_otg_ncb;
		usb_register_notifier(charger->usb_phy, &charger->otg_nb);
	}

	/* Register IRQs */
	ret = da9150_charger_register_irq(pdev, da9150_charger_chg_irq,
					  "CHG_STATUS");
	if (ret < 0)
		goto chg_irq_fail;

	ret = da9150_charger_register_irq(pdev, da9150_charger_tjunc_irq,
					  "CHG_TJUNC");
	if (ret < 0)
		goto tjunc_irq_fail;

	ret = da9150_charger_register_irq(pdev, da9150_charger_vfault_irq,
					  "CHG_VFAULT");
	if (ret < 0)
		goto vfault_irq_fail;

	ret = da9150_charger_register_irq(pdev, da9150_charger_vbus_irq,
					  "CHG_VBUS");
	if (ret < 0)
		goto vbus_irq_fail;

	return 0;


vbus_irq_fail:
	da9150_charger_unregister_irq(pdev, "CHG_VFAULT");
vfault_irq_fail:
	da9150_charger_unregister_irq(pdev, "CHG_TJUNC");
tjunc_irq_fail:
	da9150_charger_unregister_irq(pdev, "CHG_STATUS");
chg_irq_fail:
	if (!IS_ERR_OR_NULL(charger->usb_phy))
		usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
battery_fail:
	power_supply_unregister(charger->usb);

usb_fail:
	iio_channel_release(charger->vbat_chan);

vbat_chan_fail:
	iio_channel_release(charger->tjunc_chan);

tjunc_chan_fail:
	iio_channel_release(charger->vbus_chan);

vbus_chan_fail:
	iio_channel_release(charger->ibus_chan);

ibus_chan_fail:
	return ret;
}