Esempio n. 1
0
static int omap_otg_remove(struct platform_device *pdev)
{
	struct otg_device *otg_dev = platform_get_drvdata(pdev);
	struct extcon_dev *edev = otg_dev->extcon;

	extcon_unregister_notifier(edev, EXTCON_USB_HOST,&otg_dev->id_nb);
	extcon_unregister_notifier(edev, EXTCON_USB, &otg_dev->vbus_nb);

	return 0;
}
Esempio n. 2
0
static int dwc3_omap_remove(struct platform_device *pdev)
{
	struct dwc3_omap	*omap = platform_get_drvdata(pdev);

	extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb);
	extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb);
	dwc3_omap_disable_irqs(omap);
	of_platform_depopulate(omap->dev);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}
Esempio n. 3
0
static int axp288_charger_remove(struct platform_device *pdev)
{
	struct axp288_chrg_info *info =  dev_get_drvdata(&pdev->dev);

	if (info->otg.cable)
		extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST,
					&info->otg.id_nb);

	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
					&info->cable.nb);
	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
					&info->cable.nb);
	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
					&info->cable.nb);
	power_supply_unregister(info->psy_usb);

	return 0;
}
Esempio n. 4
0
static int omap_otg_probe(struct platform_device *pdev)
{
	const struct omap_usb_config *config = pdev->dev.platform_data;
	struct otg_device *otg_dev;
	struct extcon_dev *extcon;
	int ret;
	u32 rev;

	if (!config || !config->extcon)
		return -ENODEV;

	extcon = extcon_get_extcon_dev(config->extcon);
	if (!extcon)
		return -EPROBE_DEFER;

	otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL);
	if (!otg_dev)
		return -ENOMEM;

	otg_dev->base = devm_ioremap_resource(&pdev->dev, &pdev->resource[0]);
	if (IS_ERR(otg_dev->base))
		return PTR_ERR(otg_dev->base);

	otg_dev->extcon = extcon;
	otg_dev->id_nb.notifier_call = omap_otg_id_notifier;
	otg_dev->vbus_nb.notifier_call = omap_otg_vbus_notifier;

	ret = extcon_register_notifier(extcon, EXTCON_USB_HOST, &otg_dev->id_nb);
	if (ret)
		return ret;

	ret = extcon_register_notifier(extcon, EXTCON_USB, &otg_dev->vbus_nb);
	if (ret) {
		extcon_unregister_notifier(extcon, EXTCON_USB_HOST,
					&otg_dev->id_nb);
		return ret;
	}

	otg_dev->id = extcon_get_cable_state_(extcon, EXTCON_USB_HOST);
	otg_dev->vbus = extcon_get_cable_state_(extcon, EXTCON_USB);
	omap_otg_set_mode(otg_dev);

	rev = readl(otg_dev->base);

	dev_info(&pdev->dev,
		 "OMAP USB OTG controller rev %d.%d (%s, id=%d, vbus=%d)\n",
		 (rev >> 4) & 0xf, rev & 0xf, config->extcon, otg_dev->id,
		 otg_dev->vbus);

	return 0;
}
Esempio n. 5
0
static int ulpmc_battery_remove(struct i2c_client *client)
{
	struct ulpmc_chip_info *chip = i2c_get_clientdata(client);

	cancel_delayed_work_sync(&chip->work);
	if (chip->edev)
		extcon_unregister_notifier(chip->edev, &chip->nb);
	power_supply_unregister(&chip->chrg);
	power_supply_unregister(&chip->bat);
	mutex_destroy(&chip->lock);
	kfree(chip);

	return 0;
}
Esempio n. 6
0
static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
{
	struct msm_otg_platform_data *pdata;
	struct extcon_dev *ext_id, *ext_vbus;
	struct device_node *node = pdev->dev.of_node;
	struct property *prop;
	int len, ret, words;
	u32 val, tmp[3];

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	motg->pdata = pdata;

	pdata->phy_type = (enum msm_usb_phy_type)of_device_get_match_data(&pdev->dev);
	if (!pdata->phy_type)
		return 1;

	motg->link_rst = devm_reset_control_get(&pdev->dev, "link");
	if (IS_ERR(motg->link_rst))
		return PTR_ERR(motg->link_rst);

	motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy");
	if (IS_ERR(motg->phy_rst))
		motg->phy_rst = NULL;

	pdata->mode = usb_get_dr_mode(&pdev->dev);
	if (pdata->mode == USB_DR_MODE_UNKNOWN)
		pdata->mode = USB_DR_MODE_OTG;

	pdata->otg_control = OTG_PHY_CONTROL;
	if (!of_property_read_u32(node, "qcom,otg-control", &val))
		if (val == OTG_PMIC_CONTROL)
			pdata->otg_control = val;

	if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2)
		motg->phy_number = val;

	motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL;
	motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN;
	motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX;

	if (of_get_property(node, "qcom,vdd-levels", &len) &&
	    len == sizeof(tmp)) {
		of_property_read_u32_array(node, "qcom,vdd-levels",
					   tmp, len / sizeof(*tmp));
		motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE];
		motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN];
		motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX];
	}

	motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup");

	motg->switch_gpio = devm_gpiod_get_optional(&pdev->dev, "switch",
						    GPIOD_OUT_LOW);
	if (IS_ERR(motg->switch_gpio))
		return PTR_ERR(motg->switch_gpio);

	ext_id = ERR_PTR(-ENODEV);
	ext_vbus = ERR_PTR(-ENODEV);
	if (of_property_read_bool(node, "extcon")) {

		/* Each one of them is not mandatory */
		ext_vbus = extcon_get_edev_by_phandle(&pdev->dev, 0);
		if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV)
			return PTR_ERR(ext_vbus);

		ext_id = extcon_get_edev_by_phandle(&pdev->dev, 1);
		if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
			return PTR_ERR(ext_id);
	}

	if (!IS_ERR(ext_vbus)) {
		motg->vbus.extcon = ext_vbus;
		motg->vbus.nb.notifier_call = msm_otg_vbus_notifier;
		ret = extcon_register_notifier(ext_vbus, EXTCON_USB,
						&motg->vbus.nb);
		if (ret < 0) {
			dev_err(&pdev->dev, "register VBUS notifier failed\n");
			return ret;
		}

		ret = extcon_get_cable_state_(ext_vbus, EXTCON_USB);
		if (ret)
			set_bit(B_SESS_VLD, &motg->inputs);
		else
			clear_bit(B_SESS_VLD, &motg->inputs);
	}

	if (!IS_ERR(ext_id)) {
		motg->id.extcon = ext_id;
		motg->id.nb.notifier_call = msm_otg_id_notifier;
		ret = extcon_register_notifier(ext_id, EXTCON_USB_HOST,
						&motg->id.nb);
		if (ret < 0) {
			dev_err(&pdev->dev, "register ID notifier failed\n");
			extcon_unregister_notifier(motg->vbus.extcon,
						   EXTCON_USB, &motg->vbus.nb);
			return ret;
		}

		ret = extcon_get_cable_state_(ext_id, EXTCON_USB_HOST);
		if (ret)
			clear_bit(ID, &motg->inputs);
		else
			set_bit(ID, &motg->inputs);
	}

	prop = of_find_property(node, "qcom,phy-init-sequence", &len);
	if (!prop || !len)
		return 0;

	words = len / sizeof(u32);

	if (words >= ULPI_EXT_VENDOR_SPECIFIC) {
		dev_warn(&pdev->dev, "Too big PHY init sequence %d\n", words);
		return 0;
	}

	pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
	if (!pdata->phy_init_seq)
		return 0;

	ret = of_property_read_u32_array(node, "qcom,phy-init-sequence",
					 pdata->phy_init_seq, words);
	if (!ret)
		pdata->phy_init_sz = words;

	return 0;
}
Esempio n. 7
0
static int dwc3_omap_probe(struct platform_device *pdev)
{
	struct device_node	*node = pdev->dev.of_node;

	struct dwc3_omap	*omap;
	struct resource		*res;
	struct device		*dev = &pdev->dev;
	struct regulator	*vbus_reg = NULL;

	int			ret;
	int			irq;

	u32			reg;

	void __iomem		*base;

	if (!node) {
		dev_err(dev, "device node not found\n");
		return -EINVAL;
	}

	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
	if (!omap)
		return -ENOMEM;

	platform_set_drvdata(pdev, omap);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "missing IRQ resource\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	if (of_property_read_bool(node, "vbus-supply")) {
		vbus_reg = devm_regulator_get(dev, "vbus");
		if (IS_ERR(vbus_reg)) {
			dev_err(dev, "vbus init failed\n");
			return PTR_ERR(vbus_reg);
		}
	}

	omap->dev	= dev;
	omap->irq	= irq;
	omap->base	= base;
	omap->vbus_reg	= vbus_reg;

	pm_runtime_enable(dev);
	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		dev_err(dev, "get_sync failed with err %d\n", ret);
		goto err1;
	}

	dwc3_omap_map_offset(omap);
	dwc3_omap_set_utmi_mode(omap);

	/* check the DMA Status */
	reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);

	ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0,
			"dwc3-omap", omap);
	if (ret) {
		dev_err(dev, "failed to request IRQ #%d --> %d\n",
				omap->irq, ret);
		goto err1;
	}

	ret = dwc3_omap_extcon_register(omap);
	if (ret < 0)
		goto err1;

	ret = of_platform_populate(node, NULL, NULL, dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to create dwc3 core\n");
		goto err2;
	}

	dwc3_omap_enable_irqs(omap);

	return 0;

err2:
	extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb);
	extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb);

err1:
	pm_runtime_put_sync(dev);
	pm_runtime_disable(dev);

	return ret;
}
Esempio n. 8
0
static int axp288_charger_probe(struct platform_device *pdev)
{
	int ret, i, pirq;
	struct axp288_chrg_info *info;
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	struct power_supply_config charger_cfg = {};

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pdev = pdev;
	info->regmap = axp20x->regmap;
	info->regmap_irqc = axp20x->regmap_irqc;
	info->pdata = pdev->dev.platform_data;

	if (!info->pdata) {
		/* Try ACPI provided pdata via device properties */
		if (!device_property_present(&pdev->dev,
						"axp288_charger_data\n"))
			dev_err(&pdev->dev, "failed to get platform data\n");
		return -ENODEV;
	}

	info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME);
	if (info->cable.edev == NULL) {
		dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n",
			AXP288_EXTCON_DEV_NAME);
		return -EPROBE_DEFER;
	}

	/* Register for extcon notification */
	INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker);
	info->cable.nb.notifier_call = axp288_charger_handle_cable_evt;
	ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
					&info->cable.nb);
	if (ret) {
		dev_err(&info->pdev->dev,
			"failed to register extcon notifier for SDP %d\n", ret);
		return ret;
	}

	ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
					&info->cable.nb);
	if (ret) {
		dev_err(&info->pdev->dev,
			"failed to register extcon notifier for CDP %d\n", ret);
		extcon_unregister_notifier(info->cable.edev,
				EXTCON_CHG_USB_SDP, &info->cable.nb);
		return ret;
	}

	ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
					&info->cable.nb);
	if (ret) {
		dev_err(&info->pdev->dev,
			"failed to register extcon notifier for DCP %d\n", ret);
		extcon_unregister_notifier(info->cable.edev,
				EXTCON_CHG_USB_SDP, &info->cable.nb);
		extcon_unregister_notifier(info->cable.edev,
				EXTCON_CHG_USB_CDP, &info->cable.nb);
		return ret;
	}

	platform_set_drvdata(pdev, info);
	mutex_init(&info->lock);

	/* Register with power supply class */
	charger_cfg.drv_data = info;
	info->psy_usb = power_supply_register(&pdev->dev, &axp288_charger_desc,
						&charger_cfg);
	if (IS_ERR(info->psy_usb)) {
		dev_err(&pdev->dev, "failed to register power supply charger\n");
		ret = PTR_ERR(info->psy_usb);
		goto psy_reg_failed;
	}

	/* Register for OTG notification */
	INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker);
	info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt;
	ret = extcon_register_notifier(info->otg.cable, EXTCON_USB_HOST,
				       &info->otg.id_nb);
	if (ret)
		dev_warn(&pdev->dev, "failed to register otg notifier\n");

	if (info->otg.cable)
		info->otg.id_short = extcon_get_cable_state_(
					info->otg.cable, EXTCON_USB_HOST);

	/* Register charger interrupts */
	for (i = 0; i < CHRG_INTR_END; i++) {
		pirq = platform_get_irq(info->pdev, i);
		info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
		if (info->irq[i] < 0) {
			dev_warn(&info->pdev->dev,
				"failed to get virtual interrupt=%d\n", pirq);
			ret = info->irq[i];
			goto intr_reg_failed;
		}
		ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i],
					NULL, axp288_charger_irq_thread_handler,
					IRQF_ONESHOT, info->pdev->name, info);
		if (ret) {
			dev_err(&pdev->dev, "failed to request interrupt=%d\n",
								info->irq[i]);
			goto intr_reg_failed;
		}
	}

	charger_init_hw_regs(info);

	return 0;

intr_reg_failed:
	if (info->otg.cable)
		extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST,
					&info->otg.id_nb);
	power_supply_unregister(info->psy_usb);
psy_reg_failed:
	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
					&info->cable.nb);
	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
					&info->cable.nb);
	extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
					&info->cable.nb);
	return ret;
}