Example #1
0
static int arizona_map_irq(struct arizona *arizona, int irq)
{
	int ret;

	ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
	if (ret < 0)
		ret = regmap_irq_get_virq(arizona->irq_chip, irq);

	return ret;
}
Example #2
0
static int wm8994_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
	struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip);
	struct wm8994 *wm8994 = wm8994_gpio->wm8994;

	return regmap_irq_get_virq(wm8994->irq_data, offset);
}
Example #3
0
int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq)
{
	int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);

	enable_irq(virq);

	return 0;
}
Example #4
0
int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
		irq_handler_t handler, const char *name, void *dev)
{
	int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);

	return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler,
					 IRQF_ONESHOT, name, dev);
}
Example #5
0
int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq)
{
	int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);

	disable_irq_nosync(virq);

	return 0;
}
Example #6
0
int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev)
{
	int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);

	devm_free_irq(mc13xxx->dev, virq, dev);

	return 0;
}
Example #7
0
static int da9055_onkey_remove(struct platform_device *pdev)
{
	struct da9055_onkey *onkey = platform_get_drvdata(pdev);
	int irq = platform_get_irq_byname(pdev, "ONKEY");

	irq = regmap_irq_get_virq(onkey->da9055->irq_data, irq);
	free_irq(irq, onkey);
	cancel_delayed_work_sync(&onkey->work);
	input_unregister_device(onkey->input);

	return 0;
}
Example #8
0
static int da9055_rtc_probe(struct platform_device *pdev)
{
	struct da9055_rtc *rtc;
	struct da9055_pdata *pdata = NULL;
	int ret, alm_irq;

	rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9055_rtc), GFP_KERNEL);
	if (!rtc)
		return -ENOMEM;

	rtc->da9055 = dev_get_drvdata(pdev->dev.parent);
	pdata = rtc->da9055->dev->platform_data;
	platform_set_drvdata(pdev, rtc);

	ret = da9055_rtc_device_init(rtc->da9055, pdata);
	if (ret < 0)
		goto err_rtc;

	ret = da9055_reg_read(rtc->da9055, DA9055_REG_ALARM_Y);
	if (ret < 0)
		goto err_rtc;

	if (ret & DA9055_RTC_ALM_EN)
		rtc->alarm_enable = 1;

	device_init_wakeup(&pdev->dev, 1);

	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
					&da9055_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		goto err_rtc;
	}

	alm_irq = platform_get_irq_byname(pdev, "ALM");
	alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq);
	ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
					da9055_rtc_alm_irq,
					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
					"ALM", rtc);
	if (ret != 0)
		dev_err(rtc->da9055->dev, "irq registration failed: %d\n", ret);

err_rtc:
	return ret;

}
Example #9
0
static int bxt_wcove_tmu_probe(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
	struct regmap_irq_chip_data *regmap_irq_chip;
	struct wcove_tmu *wctmu;
	int ret, virq, irq;

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

	wctmu->dev = &pdev->dev;
	wctmu->regmap = pmic->regmap;

	irq = platform_get_irq(pdev, 0);

	if (irq < 0) {
		dev_err(&pdev->dev, "invalid irq %d\n", irq);
		return irq;
	}

	regmap_irq_chip = pmic->irq_chip_data_tmu;
	virq = regmap_irq_get_virq(regmap_irq_chip, irq);
	if (virq < 0) {
		dev_err(&pdev->dev,
			"failed to get virtual interrupt=%d\n", irq);
		return virq;
	}

	ret = devm_request_threaded_irq(&pdev->dev, virq,
					NULL, bxt_wcove_tmu_irq_handler,
					IRQF_ONESHOT, "bxt_wcove_tmu", wctmu);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n",
							ret, virq);
		return ret;
	}
	wctmu->irq = virq;

	/* Unmask TMU second level Wake & System alarm */
	regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
				  BXTWC_TMU_ALRM_MASK, 0);

	platform_set_drvdata(pdev, wctmu);
	return 0;
}
Example #10
0
static int max8907_rtc_probe(struct platform_device *pdev)
{
	struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
	struct max8907_rtc *rtc;
	int ret;

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

	rtc->max8907 = max8907;
	rtc->regmap = max8907->regmap_rtc;

	rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev,
					&max8907_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc->rtc_dev)) {
		ret = PTR_ERR(rtc->rtc_dev);
		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
		return ret;
	}

	rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc,
				       MAX8907_IRQ_RTC_ALARM0);
	if (rtc->irq < 0) {
		ret = rtc->irq;
		goto err_unregister;
	}

	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
				max8907_irq_handler,
				IRQF_ONESHOT, "max8907-alarm0", rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n",
			rtc->irq, ret);
		goto err_unregister;
	}

	return 0;

err_unregister:
	rtc_device_unregister(rtc->rtc_dev);
	return ret;
}
Example #11
0
static irqreturn_t da9052_bat_irq(int irq, void *data)
{
	struct da9052_battery *bat = data;
	int virq;

	virq = regmap_irq_get_virq(bat->da9052->irq_data, irq);
	irq -= virq;

	if (irq == DA9052_IRQ_CHGEND)
		bat->status = POWER_SUPPLY_STATUS_FULL;
	else
		da9052_bat_check_status(bat, NULL);

	if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN ||
	    irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) {
		power_supply_changed(&bat->psy);
	}

	return IRQ_HANDLED;
}
static int twl6040_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct twl6040_platform_data *pdata = client->dev.platform_data;
	struct device_node *node = client->dev.of_node;
	struct twl6040 *twl6040;
	struct mfd_cell *cell = NULL;
	int irq, ret, children = 0;

	if (!pdata && !node) {
		dev_err(&client->dev, "Platform data is missing\n");
		return -EINVAL;
	}

	/* In order to operate correctly we need valid interrupt config */
	if (!client->irq) {
		dev_err(&client->dev, "Invalid IRQ configuration\n");
		return -EINVAL;
	}

	twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
			       GFP_KERNEL);
	if (!twl6040) {
		ret = -ENOMEM;
		goto err;
	}

	twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config);
	if (IS_ERR(twl6040->regmap)) {
		ret = PTR_ERR(twl6040->regmap);
		goto err;
	}

	i2c_set_clientdata(client, twl6040);

	twl6040->supplies[0].supply = "vio";
	twl6040->supplies[1].supply = "v2v1";
	ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
				 twl6040->supplies);
	if (ret != 0) {
		dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
		goto regulator_get_err;
	}

	ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
	if (ret != 0) {
		dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
		goto regulator_get_err;
	}

	twl6040->dev = &client->dev;
	twl6040->irq = client->irq;

	mutex_init(&twl6040->mutex);
	init_completion(&twl6040->ready);

	twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);

	/* ERRATA: Automatic power-up is not possible in ES1.0 */
	if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) {
		if (pdata)
			twl6040->audpwron = pdata->audpwron_gpio;
		else
			twl6040->audpwron = of_get_named_gpio(node,
						"ti,audpwron-gpio", 0);
	} else
		twl6040->audpwron = -EINVAL;

	if (gpio_is_valid(twl6040->audpwron)) {
		ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
					GPIOF_OUT_INIT_LOW, "audpwron");
		if (ret)
			goto gpio_err;
	}

	ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq,
			IRQF_ONESHOT, 0, &twl6040_irq_chip,
			&twl6040->irq_data);
	if (ret < 0)
		goto gpio_err;

	twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data,
					       TWL6040_IRQ_READY);
	twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data,
					       TWL6040_IRQ_TH);

	ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL,
				   twl6040_readyint_handler, IRQF_ONESHOT,
				   "twl6040_irq_ready", twl6040);
	if (ret) {
		dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret);
		goto readyirq_err;
	}

	ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL,
				   twl6040_thint_handler, IRQF_ONESHOT,
				   "twl6040_irq_th", twl6040);
	if (ret) {
		dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
		goto thirq_err;
	}

	/* dual-access registers controlled by I2C only */
	twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);

	/*
	 * The main functionality of twl6040 to provide audio on OMAP4+ systems.
	 * We can add the ASoC codec child whenever this driver has been loaded.
	 * The ASoC codec can work without pdata, pass the platform_data only if
	 * it has been provided.
	 */
	irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG);
	cell = &twl6040->cells[children];
	cell->name = "twl6040-codec";
	twl6040_codec_rsrc[0].start = irq;
	twl6040_codec_rsrc[0].end = irq;
	cell->resources = twl6040_codec_rsrc;
	cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc);
	if (pdata && pdata->codec) {
		cell->platform_data = pdata->codec;
		cell->pdata_size = sizeof(*pdata->codec);
	}
	children++;

	if (twl6040_has_vibra(pdata, node)) {
		irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB);

		cell = &twl6040->cells[children];
		cell->name = "twl6040-vibra";
		twl6040_vibra_rsrc[0].start = irq;
		twl6040_vibra_rsrc[0].end = irq;
		cell->resources = twl6040_vibra_rsrc;
		cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc);

		if (pdata && pdata->vibra) {
			cell->platform_data = pdata->vibra;
			cell->pdata_size = sizeof(*pdata->vibra);
		}
		children++;
	}

	/*
	 * Enable the GPO driver in the following cases:
	 * DT booted kernel or legacy boot with valid gpo platform_data
	 */
	if (!pdata || (pdata && pdata->gpo)) {
		cell = &twl6040->cells[children];
		cell->name = "twl6040-gpo";

		if (pdata) {
			cell->platform_data = pdata->gpo;
			cell->pdata_size = sizeof(*pdata->gpo);
		}
		children++;
	}

	ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
			      NULL, 0, NULL);
	if (ret)
		goto mfd_err;

	return 0;

mfd_err:
	devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
thirq_err:
	devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
readyirq_err:
	regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
gpio_err:
	regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
regulator_get_err:
	i2c_set_clientdata(client, NULL);
err:
	return ret;
}
Example #13
0
static int palmas_usb_probe(struct platform_device *pdev)
{
	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
	struct palmas_usb_platform_data	*pdata = dev_get_platdata(&pdev->dev);
	struct device_node *node = pdev->dev.of_node;
	struct palmas_usb *palmas_usb;
	int status;

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

	if (node && !pdata) {
		palmas_usb->wakeup = of_property_read_bool(node, "ti,wakeup");
		palmas_usb->enable_id_detection = of_property_read_bool(node,
						"ti,enable-id-detection");
		palmas_usb->enable_vbus_detection = of_property_read_bool(node,
						"ti,enable-vbus-detection");
	} else {
		palmas_usb->wakeup = true;
		palmas_usb->enable_id_detection = true;
		palmas_usb->enable_vbus_detection = true;

		if (pdata)
			palmas_usb->wakeup = pdata->wakeup;
	}

	palmas_usb->id_gpiod = devm_gpiod_get_optional(&pdev->dev, "id",
							GPIOD_IN);
	if (IS_ERR(palmas_usb->id_gpiod)) {
		dev_err(&pdev->dev, "failed to get id gpio\n");
		return PTR_ERR(palmas_usb->id_gpiod);
	}

	palmas_usb->vbus_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus",
							GPIOD_IN);
	if (IS_ERR(palmas_usb->vbus_gpiod)) {
		dev_err(&pdev->dev, "failed to get vbus gpio\n");
		return PTR_ERR(palmas_usb->vbus_gpiod);
	}

	if (palmas_usb->enable_id_detection && palmas_usb->id_gpiod) {
		palmas_usb->enable_id_detection = false;
		palmas_usb->enable_gpio_id_detection = true;
	}

	if (palmas_usb->enable_vbus_detection && palmas_usb->vbus_gpiod) {
		palmas_usb->enable_vbus_detection = false;
		palmas_usb->enable_gpio_vbus_detection = true;
	}

	if (palmas_usb->enable_gpio_id_detection) {
		u32 debounce;

		if (of_property_read_u32(node, "debounce-delay-ms", &debounce))
			debounce = USB_GPIO_DEBOUNCE_MS;

		status = gpiod_set_debounce(palmas_usb->id_gpiod,
					    debounce * 1000);
		if (status < 0)
			palmas_usb->sw_debounce_jiffies = msecs_to_jiffies(debounce);
	}

	INIT_DELAYED_WORK(&palmas_usb->wq_detectid, palmas_gpio_id_detect);

	palmas->usb = palmas_usb;
	palmas_usb->palmas = palmas;

	palmas_usb->dev	 = &pdev->dev;

	palmas_usb_wakeup(palmas, palmas_usb->wakeup);

	platform_set_drvdata(pdev, palmas_usb);

	palmas_usb->edev = devm_extcon_dev_allocate(&pdev->dev,
						    palmas_extcon_cable);
	if (IS_ERR(palmas_usb->edev)) {
		dev_err(&pdev->dev, "failed to allocate extcon device\n");
		return -ENOMEM;
	}

	status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev);
	if (status) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return status;
	}

	if (palmas_usb->enable_id_detection) {
		palmas_usb->id_otg_irq = regmap_irq_get_virq(palmas->irq_data,
							     PALMAS_ID_OTG_IRQ);
		palmas_usb->id_irq = regmap_irq_get_virq(palmas->irq_data,
							 PALMAS_ID_IRQ);
		status = devm_request_threaded_irq(palmas_usb->dev,
				palmas_usb->id_irq,
				NULL, palmas_id_irq_handler,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
				IRQF_ONESHOT,
				"palmas_usb_id", palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
					palmas_usb->id_irq, status);
			return status;
		}
	} else if (palmas_usb->enable_gpio_id_detection) {
		palmas_usb->gpio_id_irq = gpiod_to_irq(palmas_usb->id_gpiod);
		if (palmas_usb->gpio_id_irq < 0) {
			dev_err(&pdev->dev, "failed to get id irq\n");
			return palmas_usb->gpio_id_irq;
		}
		status = devm_request_threaded_irq(&pdev->dev,
						   palmas_usb->gpio_id_irq,
						   NULL,
						   palmas_gpio_id_irq_handler,
						   IRQF_TRIGGER_RISING |
						   IRQF_TRIGGER_FALLING |
						   IRQF_ONESHOT,
						   "palmas_usb_id",
						   palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev,
				"failed to request handler for id irq\n");
			return status;
		}
	}

	if (palmas_usb->enable_vbus_detection) {
		palmas_usb->vbus_otg_irq = regmap_irq_get_virq(palmas->irq_data,
						       PALMAS_VBUS_OTG_IRQ);
		palmas_usb->vbus_irq = regmap_irq_get_virq(palmas->irq_data,
							   PALMAS_VBUS_IRQ);
		status = devm_request_threaded_irq(palmas_usb->dev,
				palmas_usb->vbus_irq, NULL,
				palmas_vbus_irq_handler,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
				IRQF_ONESHOT,
				"palmas_usb_vbus", palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
					palmas_usb->vbus_irq, status);
			return status;
		}
	} else if (palmas_usb->enable_gpio_vbus_detection) {
		/* remux GPIO_1 as VBUSDET */
		status = palmas_update_bits(palmas,
			PALMAS_PU_PD_OD_BASE,
			PALMAS_PRIMARY_SECONDARY_PAD1,
			PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK,
			(1 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT));
		if (status < 0) {
			dev_err(&pdev->dev, "can't remux GPIO1\n");
			return status;
		}

		palmas_usb->vbus_otg_irq = regmap_irq_get_virq(palmas->irq_data,
						       PALMAS_VBUS_OTG_IRQ);
		palmas_usb->gpio_vbus_irq = gpiod_to_irq(palmas_usb->vbus_gpiod);
		if (palmas_usb->gpio_vbus_irq < 0) {
			dev_err(&pdev->dev, "failed to get vbus irq\n");
			return palmas_usb->gpio_vbus_irq;
		}
		status = devm_request_threaded_irq(&pdev->dev,
						palmas_usb->gpio_vbus_irq,
						NULL,
						palmas_vbus_irq_handler,
						IRQF_TRIGGER_FALLING |
						IRQF_TRIGGER_RISING |
						IRQF_ONESHOT,
						"palmas_usb_vbus",
						palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev,
				"failed to request handler for vbus irq\n");
			return status;
		}
	}

	palmas_enable_irq(palmas_usb);
	/* perform initial detection */
	if (palmas_usb->enable_gpio_vbus_detection)
		palmas_vbus_irq_handler(palmas_usb->gpio_vbus_irq, palmas_usb);
	palmas_gpio_id_detect(&palmas_usb->wq_detectid.work);
	device_set_wakeup_capable(&pdev->dev, true);
	return 0;
}
Example #14
0
static int twl6040_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct device_node *node = client->dev.of_node;
	struct twl6040 *twl6040;
	struct mfd_cell *cell = NULL;
	int irq, ret, children = 0;

	if (!node) {
		dev_err(&client->dev, "of node is missing\n");
		return -EINVAL;
	}

	/* In order to operate correctly we need valid interrupt config */
	if (!client->irq) {
		dev_err(&client->dev, "Invalid IRQ configuration\n");
		return -EINVAL;
	}

	twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
			       GFP_KERNEL);
	if (!twl6040)
		return -ENOMEM;

	twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config);
	if (IS_ERR(twl6040->regmap))
		return PTR_ERR(twl6040->regmap);

	i2c_set_clientdata(client, twl6040);

	twl6040->clk32k = devm_clk_get(&client->dev, "clk32k");
	if (IS_ERR(twl6040->clk32k)) {
		if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		dev_dbg(&client->dev, "clk32k is not handled\n");
		twl6040->clk32k = NULL;
	}

	twl6040->mclk = devm_clk_get(&client->dev, "mclk");
	if (IS_ERR(twl6040->mclk)) {
		if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		dev_dbg(&client->dev, "mclk is not handled\n");
		twl6040->mclk = NULL;
	}

	twl6040->supplies[0].supply = "vio";
	twl6040->supplies[1].supply = "v2v1";
	ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
				      twl6040->supplies);
	if (ret != 0) {
		dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
		return ret;
	}

	ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
	if (ret != 0) {
		dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
		return ret;
	}

	twl6040->dev = &client->dev;
	twl6040->irq = client->irq;

	mutex_init(&twl6040->mutex);
	init_completion(&twl6040->ready);

	regmap_register_patch(twl6040->regmap, twl6040_patch,
			      ARRAY_SIZE(twl6040_patch));

	twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
	if (twl6040->rev < 0) {
		dev_err(&client->dev, "Failed to read revision register: %d\n",
			twl6040->rev);
		ret = twl6040->rev;
		goto gpio_err;
	}

	/* ERRATA: Automatic power-up is not possible in ES1.0 */
	if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
		twl6040->audpwron = of_get_named_gpio(node,
						      "ti,audpwron-gpio", 0);
	else
		twl6040->audpwron = -EINVAL;

	if (gpio_is_valid(twl6040->audpwron)) {
		ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
					    GPIOF_OUT_INIT_LOW, "audpwron");
		if (ret)
			goto gpio_err;

		/* Clear any pending interrupt */
		twl6040_reg_read(twl6040, TWL6040_REG_INTID);
	}

	ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT,
				  0, &twl6040_irq_chip, &twl6040->irq_data);
	if (ret < 0)
		goto gpio_err;

	twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data,
						 TWL6040_IRQ_READY);
	twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data,
					      TWL6040_IRQ_TH);

	ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL,
					twl6040_readyint_handler, IRQF_ONESHOT,
					"twl6040_irq_ready", twl6040);
	if (ret) {
		dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret);
		goto readyirq_err;
	}

	ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL,
					twl6040_thint_handler, IRQF_ONESHOT,
					"twl6040_irq_th", twl6040);
	if (ret) {
		dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
		goto readyirq_err;
	}

	/*
	 * The main functionality of twl6040 to provide audio on OMAP4+ systems.
	 * We can add the ASoC codec child whenever this driver has been loaded.
	 */
	irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG);
	cell = &twl6040->cells[children];
	cell->name = "twl6040-codec";
	twl6040_codec_rsrc[0].start = irq;
	twl6040_codec_rsrc[0].end = irq;
	cell->resources = twl6040_codec_rsrc;
	cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc);
	children++;

	/* Vibra input driver support */
	if (twl6040_has_vibra(node)) {
		irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB);

		cell = &twl6040->cells[children];
		cell->name = "twl6040-vibra";
		twl6040_vibra_rsrc[0].start = irq;
		twl6040_vibra_rsrc[0].end = irq;
		cell->resources = twl6040_vibra_rsrc;
		cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc);
		children++;
	}

	/* GPO support */
	cell = &twl6040->cells[children];
	cell->name = "twl6040-gpo";
	children++;

	/* PDM clock support  */
	cell = &twl6040->cells[children];
	cell->name = "twl6040-pdmclk";
	children++;

	/* The chip is powered down so mark regmap to cache only and dirty */
	regcache_cache_only(twl6040->regmap, true);
	regcache_mark_dirty(twl6040->regmap);

	ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
			      NULL, 0, NULL);
	if (ret)
		goto readyirq_err;

	return 0;

readyirq_err:
	regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
gpio_err:
	regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
	return ret;
}
Example #15
0
static int da9055_onkey_probe(struct platform_device *pdev)
{
	struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
	struct da9055_onkey *onkey;
	struct input_dev *input_dev;
	int irq, err;

	irq = platform_get_irq_byname(pdev, "ONKEY");
	if (irq < 0) {
		dev_err(&pdev->dev,
			"Failed to get an IRQ for input device, %d\n", irq);
		return -EINVAL;
	}

	onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
	if (!onkey) {
		dev_err(&pdev->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	onkey->input = input_dev;
	onkey->da9055 = da9055;
	input_dev->name = "da9055-onkey";
	input_dev->phys = "da9055-onkey/input0";
	input_dev->dev.parent = &pdev->dev;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);
	__set_bit(KEY_POWER, input_dev->keybit);

	INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);

	irq = regmap_irq_get_virq(da9055->irq_data, irq);
	err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				   "ONKEY", onkey);
	if (err < 0) {
		dev_err(&pdev->dev,
			"Failed to register ONKEY IRQ %d, error = %d\n",
			irq, err);
		goto err_free_input;
	}

	err = input_register_device(input_dev);
	if (err) {
		dev_err(&pdev->dev, "Unable to register input device, %d\n",
			err);
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, onkey);

	return 0;

err_free_irq:
	free_irq(irq, onkey);
	cancel_delayed_work_sync(&onkey->work);
err_free_input:
	input_free_device(input_dev);

	return err;
}
Example #16
0
static int da9063_regulator_probe(struct platform_device *pdev)
{
	struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
	struct da9063_pdata *da9063_pdata = dev_get_platdata(da9063->dev);
	struct of_regulator_match *da9063_reg_matches = NULL;
	struct da9063_regulators_pdata *regl_pdata;
	const struct da9063_dev_model *model;
	struct da9063_regulators *regulators;
	struct da9063_regulator *regl;
	struct regulator_config config;
	bool bcores_merged, bmem_bio_merged;
	int id, irq, n, n_regulators, ret, val;
	size_t size;

	regl_pdata = da9063_pdata ? da9063_pdata->regulators_pdata : NULL;

	if (!regl_pdata)
		regl_pdata = da9063_parse_regulators_dt(pdev,
							&da9063_reg_matches);

	if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) {
		dev_err(&pdev->dev,
			"No regulators defined for the platform\n");
		return PTR_ERR(regl_pdata);
	}

	/* Find regulators set for particular device model */
	for (model = regulators_models; model->regulator_info; model++) {
		if (model->dev_model == da9063->model)
			break;
	}
	if (!model->regulator_info) {
		dev_err(&pdev->dev, "Chip model not recognised (%u)\n",
			da9063->model);
		return -ENODEV;
	}

	ret = regmap_read(da9063->regmap, DA9063_REG_CONFIG_H, &val);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"Error while reading BUCKs configuration\n");
		return -EIO;
	}
	bcores_merged = val & DA9063_BCORE_MERGE;
	bmem_bio_merged = val & DA9063_BUCK_MERGE;

	n_regulators = model->n_regulators;
	if (bcores_merged)
		n_regulators -= 2; /* remove BCORE1, BCORE2 */
	else
		n_regulators--;    /* remove BCORES_MERGED */
	if (bmem_bio_merged)
		n_regulators -= 2; /* remove BMEM, BIO */
	else
		n_regulators--;    /* remove BMEM_BIO_MERGED */

	/* Allocate memory required by usable regulators */
	size = sizeof(struct da9063_regulators) +
		n_regulators * sizeof(struct da9063_regulator);
	regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
	if (!regulators) {
		dev_err(&pdev->dev, "No memory for regulators\n");
		return -ENOMEM;
	}

	regulators->n_regulators = n_regulators;
	platform_set_drvdata(pdev, regulators);

	/* Register all regulators declared in platform information */
	n = 0;
	id = 0;
	while (n < regulators->n_regulators) {
		/* Skip regulator IDs depending on merge mode configuration */
		switch (id) {
		case DA9063_ID_BCORE1:
		case DA9063_ID_BCORE2:
			if (bcores_merged) {
				id++;
				continue;
			}
			break;
		case DA9063_ID_BMEM:
		case DA9063_ID_BIO:
			if (bmem_bio_merged) {
				id++;
				continue;
			}
			break;
		case DA9063_ID_BCORES_MERGED:
			if (!bcores_merged) {
				id++;
				continue;
			}
			break;
		case DA9063_ID_BMEM_BIO_MERGED:
			if (!bmem_bio_merged) {
				id++;
				continue;
			}
			break;
		}

		/* Initialise regulator structure */
		regl = &regulators->regulator[n];
		regl->hw = da9063;
		regl->info = &model->regulator_info[id];
		regl->desc = regl->info->desc;
		regl->desc.type = REGULATOR_VOLTAGE;
		regl->desc.owner = THIS_MODULE;

		if (regl->info->mode.reg)
			regl->mode = devm_regmap_field_alloc(&pdev->dev,
					da9063->regmap, regl->info->mode);
		if (regl->info->suspend.reg)
			regl->suspend = devm_regmap_field_alloc(&pdev->dev,
					da9063->regmap, regl->info->suspend);
		if (regl->info->sleep.reg)
			regl->sleep = devm_regmap_field_alloc(&pdev->dev,
					da9063->regmap, regl->info->sleep);
		if (regl->info->suspend_sleep.reg)
			regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev,
					da9063->regmap, regl->info->suspend_sleep);
		if (regl->info->ilimit.reg)
			regl->ilimit = devm_regmap_field_alloc(&pdev->dev,
					da9063->regmap, regl->info->ilimit);

		/* Register regulator */
		memset(&config, 0, sizeof(config));
		config.dev = &pdev->dev;
		config.init_data = da9063_get_regulator_initdata(regl_pdata, id);
		config.driver_data = regl;
		if (da9063_reg_matches)
			config.of_node = da9063_reg_matches[id].of_node;
		config.regmap = da9063->regmap;
		regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
						     &config);
		if (IS_ERR(regl->rdev)) {
			dev_err(&pdev->dev,
				"Failed to register %s regulator\n",
				regl->desc.name);
			return PTR_ERR(regl->rdev);
		}
		id++;
		n++;
	}

	/* LDOs overcurrent event support */
	irq = platform_get_irq_byname(pdev, "LDO_LIM");
	if (irq < 0) {
		dev_err(&pdev->dev, "Failed to get IRQ.\n");
		return irq;
	}

	regulators->irq_ldo_lim = regmap_irq_get_virq(da9063->regmap_irq, irq);
	if (regulators->irq_ldo_lim >= 0) {
		ret = request_threaded_irq(regulators->irq_ldo_lim,
					   NULL, da9063_ldo_lim_event,
					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					   "LDO_LIM", regulators);
		if (ret) {
			dev_err(&pdev->dev,
					"Failed to request LDO_LIM IRQ.\n");
			regulators->irq_ldo_lim = -ENXIO;
		}
	}

	return 0;
}
Example #17
0
static int axp20x_usb_power_probe(struct platform_device *pdev)
{
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	struct power_supply_config psy_cfg = {};
	struct axp20x_usb_power *power;
	static const char * const axp20x_irq_names[] = { "VBUS_PLUGIN",
		"VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID", NULL };
	static const char * const axp22x_irq_names[] = {
		"VBUS_PLUGIN", "VBUS_REMOVAL", NULL };
	const char * const *irq_names;
	const struct power_supply_desc *usb_power_desc;
	int i, irq, ret;

	if (!of_device_is_available(pdev->dev.of_node))
		return -ENODEV;

	if (!axp20x) {
		dev_err(&pdev->dev, "Parent drvdata not set\n");
		return -EINVAL;
	}

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

	power->axp20x_id = (enum axp20x_variants)of_device_get_match_data(
								&pdev->dev);

	power->np = pdev->dev.of_node;
	power->regmap = axp20x->regmap;

	if (power->axp20x_id == AXP202_ID) {
		/* Enable vbus valid checking */
		ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
					 AXP20X_VBUS_MON_VBUS_VALID,
					 AXP20X_VBUS_MON_VBUS_VALID);
		if (ret)
			return ret;

		if (IS_ENABLED(CONFIG_AXP20X_ADC))
			ret = configure_iio_channels(pdev, power);
		else
			ret = configure_adc_registers(power);

		if (ret)
			return ret;

		usb_power_desc = &axp20x_usb_power_desc;
		irq_names = axp20x_irq_names;
	} else if (power->axp20x_id == AXP221_ID ||
		   power->axp20x_id == AXP223_ID) {
		usb_power_desc = &axp22x_usb_power_desc;
		irq_names = axp22x_irq_names;
	} else {
		dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
			axp20x->variant);
		return -EINVAL;
	}

	psy_cfg.of_node = pdev->dev.of_node;
	psy_cfg.drv_data = power;

	power->supply = devm_power_supply_register(&pdev->dev, usb_power_desc,
						   &psy_cfg);
	if (IS_ERR(power->supply))
		return PTR_ERR(power->supply);

	/* Request irqs after registering, as irqs may trigger immediately */
	for (i = 0; irq_names[i]; i++) {
		irq = platform_get_irq_byname(pdev, irq_names[i]);
		if (irq < 0) {
			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
				 irq_names[i], irq);
			continue;
		}
		irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
		ret = devm_request_any_context_irq(&pdev->dev, irq,
				axp20x_usb_power_irq, 0, DRVNAME, power);
		if (ret < 0)
			dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
				 irq_names[i], ret);
	}

	return 0;
}
Example #18
0
static int max14577_muic_probe(struct platform_device *pdev)
{
	struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
	struct max14577_muic_info *info;
	int delay_jiffies;
	int ret;
	int i;
	u8 id;

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

	info->dev = &pdev->dev;
	info->max14577 = max14577;

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

	INIT_WORK(&info->irq_work, max14577_muic_irq_work);

	switch (max14577->dev_type) {
	case MAXIM_DEVICE_TYPE_MAX77836:
		info->muic_irqs = max77836_muic_irqs;
		info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs);
		break;
	case MAXIM_DEVICE_TYPE_MAX14577:
	default:
		info->muic_irqs = max14577_muic_irqs;
		info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
	}

	/* Support irq domain for max14577 MUIC device */
	for (i = 0; i < info->muic_irqs_num; i++) {
		struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
		int virq = 0;

		virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
		if (virq <= 0)
			return -EINVAL;
		muic_irq->virq = virq;

		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
				max14577_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d, error :%d)\n",
				muic_irq->irq, ret);
			return ret;
		}
	}

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      max14577_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return -ENOMEM;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	/* Default h/w line path */
	info->path_usb = CTRL1_SW_USB;
	info->path_uart = CTRL1_SW_UART;
	delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);

	/* Set initial path for UART */
	max14577_muic_set_path(info, info->path_uart, true);

	/* Check revision number of MUIC device*/
	ret = max14577_read_reg(info->max14577->regmap,
			MAX14577_REG_DEVICEID, &id);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to read revision number\n");
		return ret;
	}
	dev_info(info->dev, "device ID : 0x%x\n", id);

	/* Set ADC debounce time */
	max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
			delay_jiffies);

	return ret;
}
Example #19
0
static int da9052_map_irq(struct da9052 *da9052, int irq)
{
	return regmap_irq_get_virq(da9052->irq_data, irq);
}
Example #20
0
static int palmas_usb_probe(struct platform_device *pdev)
{
	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
	struct palmas_usb_platform_data	*pdata = dev_get_platdata(&pdev->dev);
	struct device_node *node = pdev->dev.of_node;
	struct palmas_usb *palmas_usb;
	int status;

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

	if (node && !pdata) {
		palmas_usb->wakeup = of_property_read_bool(node, "ti,wakeup");
		palmas_usb->enable_id_detection = of_property_read_bool(node,
						"ti,enable-id-detection");
		palmas_usb->enable_vbus_detection = of_property_read_bool(node,
						"ti,enable-vbus-detection");
	} else {
		palmas_usb->wakeup = true;
		palmas_usb->enable_id_detection = true;
		palmas_usb->enable_vbus_detection = true;

		if (pdata)
			palmas_usb->wakeup = pdata->wakeup;
	}

	palmas->usb = palmas_usb;
	palmas_usb->palmas = palmas;

	palmas_usb->dev	 = &pdev->dev;

	palmas_usb->id_otg_irq = regmap_irq_get_virq(palmas->irq_data,
						PALMAS_ID_OTG_IRQ);
	palmas_usb->id_irq = regmap_irq_get_virq(palmas->irq_data,
						PALMAS_ID_IRQ);
	palmas_usb->vbus_otg_irq = regmap_irq_get_virq(palmas->irq_data,
						PALMAS_VBUS_OTG_IRQ);
	palmas_usb->vbus_irq = regmap_irq_get_virq(palmas->irq_data,
						PALMAS_VBUS_IRQ);

	palmas_usb_wakeup(palmas, palmas_usb->wakeup);

	platform_set_drvdata(pdev, palmas_usb);

	palmas_usb->edev.supported_cable = palmas_extcon_cable;
	palmas_usb->edev.dev.parent = palmas_usb->dev;
	palmas_usb->edev.name = kstrdup(node->name, GFP_KERNEL);
	palmas_usb->edev.mutually_exclusive = mutually_exclusive;

	status = extcon_dev_register(&palmas_usb->edev);
	if (status) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		kfree(palmas_usb->edev.name);
		return status;
	}

	if (palmas_usb->enable_id_detection) {
		status = devm_request_threaded_irq(palmas_usb->dev,
				palmas_usb->id_irq,
				NULL, palmas_id_irq_handler,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
				IRQF_ONESHOT | IRQF_EARLY_RESUME,
				"palmas_usb_id", palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
					palmas_usb->id_irq, status);
			goto fail_extcon;
		}
	}

	if (palmas_usb->enable_vbus_detection) {
		status = devm_request_threaded_irq(palmas_usb->dev,
				palmas_usb->vbus_irq, NULL,
				palmas_vbus_irq_handler,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
				IRQF_ONESHOT | IRQF_EARLY_RESUME,
				"palmas_usb_vbus", palmas_usb);
		if (status < 0) {
			dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
					palmas_usb->vbus_irq, status);
			goto fail_extcon;
		}
	}

	palmas_enable_irq(palmas_usb);
	device_set_wakeup_capable(&pdev->dev, true);
	return 0;

fail_extcon:
	extcon_dev_unregister(&palmas_usb->edev);
	kfree(palmas_usb->edev.name);

	return status;
}
Example #21
0
static int max77693_muic_probe(struct platform_device *pdev)
{
	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
	struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
	struct max77693_muic_info *info;
	struct max77693_reg_data *init_data;
	int num_init_data;
	int delay_jiffies;
	int ret;
	int i;
	unsigned int id;

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

	info->dev = &pdev->dev;
	info->max77693 = max77693;
	if (info->max77693->regmap_muic) {
		dev_dbg(&pdev->dev, "allocate register map\n");
	} else {
		info->max77693->regmap_muic = devm_regmap_init_i2c(
						info->max77693->i2c_muic,
						&max77693_muic_regmap_config);
		if (IS_ERR(info->max77693->regmap_muic)) {
			ret = PTR_ERR(info->max77693->regmap_muic);
			dev_err(max77693->dev,
				"failed to allocate register map: %d\n", ret);
			return ret;
		}
	}

	/* Register input device for button of dock device */
	info->dock = devm_input_allocate_device(&pdev->dev);
	if (!info->dock) {
		dev_err(&pdev->dev, "%s: failed to allocate input\n", __func__);
		return -ENOMEM;
	}
	info->dock->name = "max77693-muic/dock";
	info->dock->phys = "max77693-muic/extcon";
	info->dock->dev.parent = &pdev->dev;

	__set_bit(EV_REP, info->dock->evbit);

	input_set_capability(info->dock, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(info->dock, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(info->dock, EV_KEY, KEY_PLAYPAUSE);
	input_set_capability(info->dock, EV_KEY, KEY_PREVIOUSSONG);
	input_set_capability(info->dock, EV_KEY, KEY_NEXTSONG);

	ret = input_register_device(info->dock);
	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot register input device error(%d)\n",
				ret);
		return ret;
	}

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

	INIT_WORK(&info->irq_work, max77693_muic_irq_work);

	/* Support irq domain for MAX77693 MUIC device */
	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
		struct max77693_muic_irq *muic_irq = &muic_irqs[i];
		int virq;

		virq = regmap_irq_get_virq(max77693->irq_data_muic,
					muic_irq->irq);
		if (virq <= 0)
			return -EINVAL;
		muic_irq->virq = virq;

		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
				max77693_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d, error :%d)\n",
				muic_irq->irq, ret);
			return ret;
		}
	}

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      max77693_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return -ENOMEM;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	/* Initialize MUIC register by using platform data or default data */
	if (pdata && pdata->muic_data) {
		init_data = pdata->muic_data->init_data;
		num_init_data = pdata->muic_data->num_init_data;
	} else {
		init_data = default_init_data;
		num_init_data = ARRAY_SIZE(default_init_data);
	}

	for (i = 0; i < num_init_data; i++) {
		regmap_write(info->max77693->regmap_muic,
				init_data[i].addr,
				init_data[i].data);
	}

	if (pdata && pdata->muic_data) {
		struct max77693_muic_platform_data *muic_pdata
						   = pdata->muic_data;

		/*
		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
		 * h/w path of COMP2/COMN1 on CONTROL1 register.
		 */
		if (muic_pdata->path_uart)
			info->path_uart = muic_pdata->path_uart;
		else
			info->path_uart = MAX77693_CONTROL1_SW_UART;

		if (muic_pdata->path_usb)
			info->path_usb = muic_pdata->path_usb;
		else
			info->path_usb = MAX77693_CONTROL1_SW_USB;

		/*
		 * Default delay time for detecting cable state
		 * after certain time.
		 */
		if (muic_pdata->detcable_delay_ms)
			delay_jiffies =
				msecs_to_jiffies(muic_pdata->detcable_delay_ms);
		else
			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	} else {
		info->path_usb = MAX77693_CONTROL1_SW_USB;
		info->path_uart = MAX77693_CONTROL1_SW_UART;
		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	}

	/* Set initial path for UART */
	 max77693_muic_set_path(info, info->path_uart, true);

	/* Check revision number of MUIC device*/
	ret = regmap_read(info->max77693->regmap_muic,
			MAX77693_MUIC_REG_ID, &id);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to read revision number\n");
		return ret;
	}
	dev_info(info->dev, "device ID : 0x%x\n", id);

	/* Set ADC debounce time */
	max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
			delay_jiffies);

	return ret;
}
Example #22
0
static int axp288_extcon_probe(struct platform_device *pdev)
{
	struct axp288_extcon_info *info;
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	int ret, i, pirq, gpio;

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

	info->dev = &pdev->dev;
	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_extcon_data\n"))
			dev_err(&pdev->dev, "failed to get platform data\n");
		return -ENODEV;
	}
	platform_set_drvdata(pdev, info);

	axp288_extcon_log_rsi(info);

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      axp288_extcon_cables);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return PTR_ERR(info->edev);
	}

	/* Register extcon device */
	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	/* Get otg transceiver phy */
	info->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
	if (IS_ERR(info->otg)) {
		dev_err(&pdev->dev, "failed to get otg transceiver\n");
		return PTR_ERR(info->otg);
	}

	/* Set up gpio control for USB Mux */
	if (info->pdata->gpio_mux_cntl) {
		gpio = desc_to_gpio(info->pdata->gpio_mux_cntl);
		ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX");
		if (ret < 0) {
			dev_err(&pdev->dev,
				"failed to request the gpio=%d\n", gpio);
			return ret;
		}
		gpiod_direction_output(info->pdata->gpio_mux_cntl,
						EXTCON_GPIO_MUX_SEL_PMIC);
	}

	for (i = 0; i < EXTCON_IRQ_END; i++) {
		pirq = platform_get_irq(pdev, i);
		info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
		if (info->irq[i] < 0) {
			dev_err(&pdev->dev,
				"failed to get virtual interrupt=%d\n", pirq);
			ret = info->irq[i];
			return ret;
		}

		ret = devm_request_threaded_irq(&pdev->dev, info->irq[i],
				NULL, axp288_extcon_isr,
				IRQF_ONESHOT | IRQF_NO_SUSPEND,
				pdev->name, info);
		if (ret) {
			dev_err(&pdev->dev, "failed to request interrupt=%d\n",
							info->irq[i]);
			return ret;
		}
	}

	/* Enable interrupts */
	axp288_extcon_enable_irq(info);

	return 0;
}
Example #23
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;
}
Example #24
0
static int max77686_rtc_probe(struct platform_device *pdev)
{
	struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent);
	struct max77686_rtc_info *info;
	int ret;

	dev_info(&pdev->dev, "%s\n", __func__);

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

	mutex_init(&info->lock);
	info->dev = &pdev->dev;
	info->max77686 = max77686;
	info->rtc = max77686->rtc;

	platform_set_drvdata(pdev, info);

	ret = max77686_rtc_init_reg(info);

	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret);
		goto err_rtc;
	}

	device_init_wakeup(&pdev->dev, 1);

	info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
					&max77686_rtc_ops, THIS_MODULE);

	if (IS_ERR(info->rtc_dev)) {
		ret = PTR_ERR(info->rtc_dev);
		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
		if (ret == 0)
			ret = -EINVAL;
		goto err_rtc;
	}

	if (!max77686->rtc_irq_data) {
		ret = -EINVAL;
		dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__);
		goto err_rtc;
	}

	info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
					 MAX77686_RTCIRQ_RTCA1);
	if (info->virq <= 0) {
		ret = -ENXIO;
		goto err_rtc;
	}

	ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
				max77686_rtc_alarm_irq, 0, "rtc-alarm1", info);
	if (ret < 0)
		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
			info->virq, ret);

err_rtc:
	return ret;
}