Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94370776 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wsa881x: Fix GPIO leak issue"

parents 464701f8 801c57e6
Loading
Loading
Loading
Loading
+23 −43
Original line number Diff line number Diff line
@@ -67,6 +67,27 @@ static void swr_dev_release(struct device *dev)
	kfree(swr_dev);
}

/**
 * swr_remove_device - remove a soundwire device
 * @swr_dev: soundwire device to remove
 *
 * Remove a soundwire device. Go through the soundwire
 * device list that master has and remove swr_dev from
 * it.
 */
void swr_remove_device(struct swr_device *swr_dev)
{
	struct swr_device *swr_dev_loop, *safe;

	list_for_each_entry_safe(swr_dev_loop, safe,
				 &swr_dev->master->devices,
				 dev_list) {
		if (swr_dev == swr_dev_loop)
			list_del(&swr_dev_loop->dev_list);
	}
}
EXPORT_SYMBOL(swr_remove_device);

/**
 * swr_new_device - instantiate a new soundwire device
 * @master: Controller to which device is connected
@@ -127,47 +148,6 @@ struct swr_device *swr_new_device(struct swr_master *master,
}
EXPORT_SYMBOL(swr_new_device);

/**
 * swr_startup_devices - perform additional initialization for child devices
 *
 * @swr_dev: pointer to soundwire slave device
 *
 * Performs any additional initialization needed for a soundwire slave device.
 * This is a optional functionality defined by slave devices.
 * Removes the slave node from the list, in case there is any failure.
 */
int swr_startup_devices(struct swr_device *swr_dev)
{
	struct swr_driver *swr_drv;
	struct device *dev;
	int ret = 0;

	if (!swr_dev)
		return -EINVAL;

	dev = &swr_dev->dev;
	if (!dev)
		return -EINVAL;

	swr_drv = to_swr_driver(dev->driver);
	if (!swr_drv)
		return -EINVAL;

	if (swr_drv->startup) {
		ret = swr_drv->startup(swr_dev);
		if (ret)
			goto out;

		dev_dbg(&swr_dev->dev,
			"%s: startup complete for device %lx\n",
			__func__, swr_dev->addr);
	}

out:
	return ret;
}
EXPORT_SYMBOL(swr_startup_devices);

/**
 * of_register_swr_devices - register child devices on to the soundwire bus
 * @master: pointer to soundwire master device
@@ -605,7 +585,7 @@ int swr_device_up(struct swr_device *swr_dev)
	dev = &swr_dev->dev;
	sdrv = to_swr_driver(dev->driver);
	if (!sdrv)
		return -EINVAL;
		return 0;

	if (sdrv->device_up)
		return sdrv->device_up(to_swr_device(dev));
@@ -633,7 +613,7 @@ int swr_device_down(struct swr_device *swr_dev)
	dev = &swr_dev->dev;
	sdrv = to_swr_driver(dev->driver);
	if (!sdrv)
		return -EINVAL;
		return 0;

	if (sdrv->device_down)
		return sdrv->device_down(to_swr_device(dev));
+3 −11
Original line number Diff line number Diff line
@@ -1355,7 +1355,6 @@ static int swrm_probe(struct platform_device *pdev)
{
	struct swr_mstr_ctrl *swrm;
	struct swr_ctrl_platform_data *pdata;
	struct swr_device *swr_dev, *safe;
	int ret;

	/* Allocate soundwire master driver structure */
@@ -1454,9 +1453,6 @@ static int swrm_probe(struct platform_device *pdev)
		goto err_mstr_fail;
	}

	if (pdev->dev.of_node)
		of_register_swr_devices(&swrm->master);

	/* Add devices registered with board-info as the
	 * controller will be up now
	 */
@@ -1472,15 +1468,11 @@ static int swrm_probe(struct platform_device *pdev)
		goto err_mstr_fail;
	}

	/* Enumerate slave devices */
	list_for_each_entry_safe(swr_dev, safe, &swrm->master.devices,
				 dev_list) {
		ret = swr_startup_devices(swr_dev);
		if (ret)
			list_del(&swr_dev->dev_list);
	}
	mutex_unlock(&swrm->mlock);

	if (pdev->dev.of_node)
		of_register_swr_devices(&swrm->master);

	dbgswrm = swrm;
	debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
	if (!IS_ERR(debugfs_swrm_dent)) {
+2 −2
Original line number Diff line number Diff line
@@ -196,7 +196,6 @@ static inline struct swr_device *to_swr_device(struct device *dev)
 * @shutdown: standard shutdown callback used during power down/halt
 * @suspend: standard suspend callback used during system suspend
 * @resume: standard resume callback used during system resume
 * @startup: additional init operation for slave devices
 * @driver: soundwire device drivers should initialize name and
 * owner field of this structure
 * @id_table: list of soundwire devices supported by this driver
@@ -210,7 +209,6 @@ struct swr_driver {
	int	(*device_up)(struct swr_device *swr);
	int	(*device_down)(struct swr_device *swr);
	int	(*reset_device)(struct swr_device *swr);
	int	(*startup)(struct swr_device *swr);
	struct device_driver		driver;
	const struct swr_device_id	*id_table;
};
@@ -309,4 +307,6 @@ extern int swr_reset_device(struct swr_device *swr_dev);
extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num,
				       bool enable);
extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num);

extern void swr_remove_device(struct swr_device *swr_dev);
#endif /* _LINUX_SOUNDWIRE_H */
+42 −49
Original line number Diff line number Diff line
@@ -1092,54 +1092,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wsa881x = {
	},
};

static int wsa881x_swr_startup(struct swr_device *swr_dev)
{
	int ret = 0;
	u8 devnum = 0;
	struct wsa881x_priv *wsa881x;

	wsa881x = swr_get_dev_data(swr_dev);
	if (!wsa881x) {
		dev_err(&swr_dev->dev, "%s: wsa881x is NULL\n", __func__);
		return -EINVAL;
	}

	/*
	 * Add 5msec delay to provide sufficient time for
	 * soundwire auto enumeration of slave devices as
	 * as per HW requirement.
	 */
	usleep_range(5000, 5010);
	ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
	if (ret) {
		dev_dbg(&swr_dev->dev,
			"%s get devnum %d for dev addr %lx failed\n",
			__func__, devnum, swr_dev->addr);
		goto err;
	}
	swr_dev->dev_num = devnum;

	wsa881x->regmap = devm_regmap_init_swr(swr_dev,
					       &wsa881x_regmap_config);
	if (IS_ERR(wsa881x->regmap)) {
		ret = PTR_ERR(wsa881x->regmap);
		dev_err(&swr_dev->dev, "%s: regmap_init failed %d\n",
			__func__, ret);
		goto err;
	}

	ret = snd_soc_register_codec(&swr_dev->dev, &soc_codec_dev_wsa881x,
				     NULL, 0);
	if (ret) {
		dev_err(&swr_dev->dev, "%s: Codec registration failed\n",
			__func__);
		goto err;
	}

err:
	return ret;
}

static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable)
{
	int ret = 0;
@@ -1201,6 +1153,8 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
{
	int ret = 0;
	struct wsa881x_priv *wsa881x;
	u8 devnum = 0;
	bool pin_state_current = false;

	wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv),
			    GFP_KERNEL);
@@ -1231,6 +1185,9 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
		if (ret)
			goto err;
	}
	if (wsa881x->wsa_rst_np)
		pin_state_current = msm_cdc_pinctrl_get_state(
						wsa881x->wsa_rst_np);
	wsa881x_gpio_ctrl(wsa881x, true);
	wsa881x->state = WSA881X_DEV_UP;

@@ -1257,8 +1214,45 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
						&codec_debug_ops);
		}
	}

	/*
	 * Add 5msec delay to provide sufficient time for
	 * soundwire auto enumeration of slave devices as
	 * as per HW requirement.
	 */
	usleep_range(5000, 5010);
	ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
	if (ret) {
		dev_dbg(&pdev->dev,
			"%s get devnum %d for dev addr %lx failed\n",
			__func__, devnum, pdev->addr);
		goto dev_err;
	}
	pdev->dev_num = devnum;

	wsa881x->regmap = devm_regmap_init_swr(pdev,
					       &wsa881x_regmap_config);
	if (IS_ERR(wsa881x->regmap)) {
		ret = PTR_ERR(wsa881x->regmap);
		dev_err(&pdev->dev, "%s: regmap_init failed %d\n",
			__func__, ret);
		goto dev_err;
	}

	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wsa881x,
				     NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "%s: Codec registration failed\n",
			__func__);
		goto dev_err;
	}

	return 0;

dev_err:
	if (pin_state_current == false)
		wsa881x_gpio_ctrl(wsa881x, false);
	swr_remove_device(pdev);
err:
	return ret;
}
@@ -1392,7 +1386,6 @@ static struct swr_driver wsa881x_codec_driver = {
	.device_up = wsa881x_swr_up,
	.device_down = wsa881x_swr_down,
	.reset_device = wsa881x_swr_reset,
	.startup = wsa881x_swr_startup,
};

static int __init wsa881x_codec_init(void)