Esempio n. 1
0
static int aic31xx_codec_probe(struct snd_soc_codec *codec)
{
	int ret = 0;
	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
	int i;

	dev_dbg(aic31xx->dev, "## %s\n", __func__);

	aic31xx = snd_soc_codec_get_drvdata(codec);

	aic31xx->codec = codec;

	for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
		aic31xx->disable_nb[i].nb.notifier_call =
			aic31xx_regulator_event;
		aic31xx->disable_nb[i].aic31xx = aic31xx;
		ret = regulator_register_notifier(aic31xx->supplies[i].consumer,
						  &aic31xx->disable_nb[i].nb);
		if (ret) {
			dev_err(codec->dev,
				"Failed to request regulator notifier: %d\n",
				ret);
			return ret;
		}
	}

	regcache_cache_only(aic31xx->regmap, true);
	regcache_mark_dirty(aic31xx->regmap);

	ret = aic31xx_add_controls(codec);
	if (ret)
		return ret;

	ret = aic31xx_add_widgets(codec);

	return ret;
}
Esempio n. 2
0
static int wm8994_resume(struct device *dev)
{
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	/* We may have lied to the PM core about suspending */
	if (!wm8994->suspended)
		return 0;

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

	regcache_cache_only(wm8994->regmap, false);
	ret = regcache_sync(wm8994->regmap);
	if (ret != 0) {
		dev_err(dev, "Failed to restore register map: %d\n", ret);
		goto err_enable;
	}

	/* Disable LDO pulldowns while the device is active */
	wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
			WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
			0);

	wm8994->suspended = false;

	return 0;

err_enable:
	regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);

	return ret;
}
Esempio n. 3
0
static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
				  enum snd_soc_bias_level level)
{
	struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);

	switch (level) {
	case SND_SOC_BIAS_ON:
		snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 0);
		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 0);
		break;

	case SND_SOC_BIAS_PREPARE:
		break;

	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
			regcache_cache_only(cs42l73->regmap, false);
			regcache_sync(cs42l73->regmap);
		}
		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
		break;

	case SND_SOC_BIAS_OFF:
		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
		if (cs42l73->shutdwn_delay > 0) {
			mdelay(cs42l73->shutdwn_delay);
			cs42l73->shutdwn_delay = 0;
		} else {
			mdelay(15); /* Min amount of time requred to power
				     * down.
				     */
		}
		snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
		break;
	}
	return 0;
}
Esempio n. 4
0
static int pcm512x_resume(struct device *dev)
{
	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
	int ret;

	if (!IS_ERR(pcm512x->sclk)) {
		ret = clk_prepare_enable(pcm512x->sclk);
		if (ret != 0) {
			dev_err(dev, "Failed to enable SCLK: %d\n", ret);
			return ret;
		}
	}

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

	regcache_cache_only(pcm512x->regmap, false);
	ret = regcache_sync(pcm512x->regmap);
	if (ret != 0) {
		dev_err(dev, "Failed to sync cache: %d\n", ret);
		return ret;
	}

	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
				 PCM512x_RQPD, 0);
	if (ret != 0) {
		dev_err(dev, "Failed to remove power down: %d\n", ret);
		return ret;
	}

	return 0;
}
Esempio n. 5
0
static int wm8994_suspend(struct device *dev)
{
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	/* Don't actually go through with the suspend if the CODEC is
	 * still active for accessory detect. */
	switch (wm8994->type) {
	case WM8958:
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
		if (ret < 0) {
			dev_err(dev, "Failed to read power status: %d\n", ret);
		} else if (ret & WM8958_MICD_ENA) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	/* Disable LDO pulldowns while the device is suspended if we
	 * don't know that something will be driving them. */
	if (!wm8994->ldo_ena_always_driven)
		wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);

	/* Explicitly put the device into reset in case regulators
	 * don't get disabled in order to ensure consistent restart.
	 */
	wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
			 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));

	regcache_mark_dirty(wm8994->regmap);

	/* Restore GPIO registers to prevent problems with mismatched
	 * pin configurations.
	 */
	ret = regcache_sync_region(wm8994->regmap, WM8994_GPIO_1,
				   WM8994_GPIO_11);
	if (ret != 0)
		dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);

	/* In case one of the GPIOs is used as a wake input. */
	ret = regcache_sync_region(wm8994->regmap,
				   WM8994_INTERRUPT_STATUS_1_MASK,
				   WM8994_INTERRUPT_STATUS_1_MASK);
	if (ret != 0)
		dev_err(dev, "Failed to restore interrupt mask: %d\n", ret);

	regcache_cache_only(wm8994->regmap, true);
	wm8994->suspended = true;

	ret = regulator_bulk_disable(wm8994->num_supplies,
				     wm8994->supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to disable supplies: %d\n", ret);
		return ret;
	}

	return 0;
}
static int tegra30_dam_probe(struct platform_device *pdev)
{
	struct resource *res,  *region;
	struct tegra30_dam_context *dam;
	int ret = 0;
	int clkm_rate;
	u32 val32;

	if (pdev->dev.of_node) {
		of_property_read_u32(pdev->dev.of_node, "nvidia,ahub-dam-id",
			&val32);
		pdev->id = (int)val32;
	}

	if ((pdev->id < 0) ||
		(pdev->id >= TEGRA30_NR_DAM_IFC)) {
		dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
		return -EINVAL;
	}

	dams_cont_info[pdev->id] = devm_kzalloc(&pdev->dev,
					sizeof(struct tegra30_dam_context),
					GFP_KERNEL);
	if (!dams_cont_info[pdev->id]) {
		dev_err(&pdev->dev, "Can't allocate dam context\n");
		ret = -ENOMEM;
		goto exit;
	}
	dams_cont_info[pdev->id]->dev = &pdev->dev;

	dam = dams_cont_info[pdev->id];
	dev_set_drvdata(&pdev->dev, dam);

	dam->dam_clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(dam->dam_clk)) {
		dev_err(&pdev->dev, "Can't retrieve dam clock\n");
		ret = PTR_ERR(dam->dam_clk);
		goto err_free;
	}
	clkm_rate = clk_get_rate(clk_get_parent(dam->dam_clk));
	while (clkm_rate > 13000000)
		clkm_rate >>= 1;

	clk_set_rate(dam->dam_clk,clkm_rate);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "No memory 0 resource\n");
		ret = -ENODEV;
		goto err_clk_put_dam;
	}

	region = devm_request_mem_region(&pdev->dev, res->start,
			resource_size(res), pdev->name);
	if (!region) {
		dev_err(&pdev->dev, "Memory region 0 already claimed\n");
		ret = -EBUSY;
		goto err_clk_put_dam;
	}

	dam->damregs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!dam->damregs) {
		dev_err(&pdev->dev, "ioremap 0 failed\n");
		ret = -ENOMEM;
		goto err_clk_put_dam;
	}

	dam->regmap = devm_regmap_init_mmio(&pdev->dev, dam->damregs,
				    &tegra30_dam_regmap_config);
	if (IS_ERR(dam->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(dam->regmap);
		goto err_clk_put_dam;
	}
	regcache_cache_only(dam->regmap, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_dam_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	tegra30_dam_debug_add(dam, pdev->id);

	return 0;

err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put_dam:
	clk_put(dam->dam_clk);
err_free:
	dams_cont_info[pdev->id] = NULL;
exit:
	return ret;
}
Esempio n. 7
0
static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
				       const struct i2c_device_id *id) {
	struct cs35l32_private *cs35l32;
	struct device_node *np = i2c_client->dev.of_node;
	u32 val32;
	int ret;
	unsigned int devid = 0;
	unsigned int reg;
	
	
	cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private),
			       GFP_KERNEL);
	if (!cs35l32) {
		dev_err(&i2c_client->dev, "could not allocate codec\n");
		return -ENOMEM;
	}

	i2c_set_clientdata(i2c_client, cs35l32);

	cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap);
	if (IS_ERR(cs35l32->regmap)) {
		ret = PTR_ERR(cs35l32->regmap);
		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
		return ret;
	}

	if (of_property_read_u32(np, "cs35l32,boost-mng", &val32) >= 0)
		cs35l32->pdata.boost_mng = val32;
	
	if (of_property_read_u32(np, "cs35l32,sdout-datacfg", &val32) >= 0)
		cs35l32->pdata.sdout_datacfg = val32;
		
	if (of_property_read_u32(np, "cs35l32,sdout-share", &val32) >= 0)
		cs35l32->pdata.sdout_share = val32;

	cs35l32->pdata.gpio_nreset = of_get_named_gpio_flags(np,
								"cs35l32,gpio-nreset", 0, NULL);

	ret = gpio_request(cs35l32->pdata.gpio_nreset, "cs35l32 reset");
	if (ret < 0) {
		dev_err(&i2c_client->dev,
			 "failed to request the gpio %d\n",
				cs35l32->pdata.gpio_nreset);
		return ret;
	}
	/*bring the chip out of reset*/
	gpio_direction_output(cs35l32->pdata.gpio_nreset, 0);
	msleep(20);
	gpio_set_value_cansleep(cs35l32->pdata.gpio_nreset, 1);
	msleep(20);

	ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
				    ARRAY_SIZE(cs35l32_monitor_patch));
	if (ret < 0) {
		dev_err(&i2c_client->dev, "failed to register regmap(try again : 0x40)\n");
		i2c_client->addr = 0x40;
		ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
				    ARRAY_SIZE(cs35l32_monitor_patch));
		if (ret < 0)
			dev_err(&i2c_client->dev, "failed to register regmap retry again\n");
	}

	/* initialize codec */
	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg);
	devid = (reg & 0xFF) << 12;

	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, &reg);
	devid |= (reg & 0xFF) << 4;

	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, &reg);
	devid |= (reg & 0xF0) >> 4;

	if ((devid != CS35L32_CHIP_ID) && (devid != CS35L32_CHIP_ID_VZW)) {
		ret = -ENODEV;
		dev_err(&i2c_client->dev,
			"CS35L32 Device ID (%X). Expected %X\n",
			devid, CS35L32_CHIP_ID);
		return ret;
	}

	ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, &reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
		return ret;;
	}

	dev_info(&i2c_client->dev,
		 "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF);

	regcache_cache_only(cs35l32->regmap, false);

	ret =  snd_soc_register_codec(&i2c_client->dev,
			&soc_codec_dev_cs35l32, cs35l32_dai, ARRAY_SIZE(cs35l32_dai));
	
	if (ret < 0)
		return ret;
	return 0;
}
static int max98925_resume(struct device *dev)
{
	regcache_cache_only(max98925_data->regmapL, false);
	return regcache_sync(max98925_data->regmapL);
}
Esempio n. 9
0
static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
				       const struct i2c_device_id *id)
{
	struct cs35l33_private *cs35l33;
	struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev);
	int ret, devid, i;
	unsigned int reg;

	cs35l33 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l33_private),
			       GFP_KERNEL);
	if (!cs35l33)
		return -ENOMEM;

	i2c_set_clientdata(i2c_client, cs35l33);
	cs35l33->regmap = devm_regmap_init_i2c(i2c_client, &cs35l33_regmap);
	if (IS_ERR(cs35l33->regmap)) {
		ret = PTR_ERR(cs35l33->regmap);
		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
		return ret;
	}

	regcache_cache_only(cs35l33->regmap, true);

	for (i = 0; i < ARRAY_SIZE(cs35l33_core_supplies); i++)
		cs35l33->core_supplies[i].supply
			= cs35l33_core_supplies[i];
	cs35l33->num_core_supplies = ARRAY_SIZE(cs35l33_core_supplies);

	ret = devm_regulator_bulk_get(&i2c_client->dev,
			cs35l33->num_core_supplies,
			cs35l33->core_supplies);
	if (ret != 0) {
		dev_err(&i2c_client->dev,
			"Failed to request core supplies: %d\n",
			ret);
		return ret;
	}

	if (pdata) {
		cs35l33->pdata = *pdata;
	} else {
		cs35l33_of_get_pdata(&i2c_client->dev, cs35l33);
		pdata = &cs35l33->pdata;
	}

	ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,
			cs35l33_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
			"cs35l33", cs35l33);
	if (ret != 0)
		dev_warn(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);

	/* We could issue !RST or skip it based on AMP topology */
	cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
			"reset-gpios", GPIOD_OUT_HIGH);
	if (IS_ERR(cs35l33->reset_gpio)) {
		dev_err(&i2c_client->dev, "%s ERROR: Can't get reset GPIO\n",
			__func__);
		return PTR_ERR(cs35l33->reset_gpio);
	}

	ret = regulator_bulk_enable(cs35l33->num_core_supplies,
					cs35l33->core_supplies);
	if (ret != 0) {
		dev_err(&i2c_client->dev,
			"Failed to enable core supplies: %d\n",
			ret);
		return ret;
	}

	gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);

	msleep(CS35L33_BOOT_DELAY);
	regcache_cache_only(cs35l33->regmap, false);

	/* initialize codec */
	ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_AB, &reg);
	devid = (reg & 0xFF) << 12;
	ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_CD, &reg);
	devid |= (reg & 0xFF) << 4;
	ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_E, &reg);
	devid |= (reg & 0xF0) >> 4;

	if (devid != CS35L33_CHIP_ID) {
		dev_err(&i2c_client->dev,
			"CS35L33 Device ID (%X). Expected ID %X\n",
			devid, CS35L33_CHIP_ID);
		goto err_enable;
	}

	ret = regmap_read(cs35l33->regmap, CS35L33_REV_ID, &reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
		goto err_enable;
	}

	dev_info(&i2c_client->dev,
		 "Cirrus Logic CS35L33, Revision: %02X\n", reg & 0xFF);

	ret = regmap_register_patch(cs35l33->regmap,
			cs35l33_patch, ARRAY_SIZE(cs35l33_patch));
	if (ret < 0) {
		dev_err(&i2c_client->dev,
			"Error in applying regmap patch: %d\n", ret);
		goto err_enable;
	}

	/* disable mclk and tdm */
	regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
		CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM,
		CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM);

	pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100);
	pm_runtime_use_autosuspend(&i2c_client->dev);
	pm_runtime_set_active(&i2c_client->dev);
	pm_runtime_enable(&i2c_client->dev);

	ret = devm_snd_soc_register_component(&i2c_client->dev,
			&soc_component_dev_cs35l33, &cs35l33_dai, 1);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "%s: Register component failed\n",
			__func__);
		goto err_enable;
	}

	return 0;

err_enable:
	regulator_bulk_disable(cs35l33->num_core_supplies,
			       cs35l33->core_supplies);

	return ret;
}
Esempio n. 10
0
int arizona_dev_init(struct arizona *arizona)
{
	struct device *dev = arizona->dev;
	const char *type_name;
	unsigned int reg, val;
	int (*apply_patch)(struct arizona *) = NULL;
	int ret, i;

	dev_set_drvdata(arizona->dev, arizona);
	mutex_init(&arizona->clk_lock);

	if (dev_get_platdata(arizona->dev))
		memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
		       sizeof(arizona->pdata));
	else
		arizona_of_get_core_pdata(arizona);

	regcache_cache_only(arizona->regmap, true);

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8997:
		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
			arizona->core_supplies[i].supply
				= wm5102_core_supplies[i];
		arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
		break;
	default:
		dev_err(arizona->dev, "Unknown device type %d\n",
			arizona->type);
		return -EINVAL;
	}

	/* Mark DCVDD as external, LDO1 driver will clear if internal */
	arizona->external_dcvdd = true;

	ret = mfd_add_devices(arizona->dev, -1, early_devs,
			      ARRAY_SIZE(early_devs), NULL, 0, NULL);
	if (ret != 0) {
		dev_err(dev, "Failed to add early children: %d\n", ret);
		return ret;
	}

	ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
				      arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to request core supplies: %d\n",
			ret);
		goto err_early;
	}

	/**
	 * Don't use devres here because the only device we have to get
	 * against is the MFD device and DCVDD will likely be supplied by
	 * one of its children. Meaning that the regulator will be
	 * destroyed by the time devres calls regulator put.
	 */
	arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
	if (IS_ERR(arizona->dcvdd)) {
		ret = PTR_ERR(arizona->dcvdd);
		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
		goto err_early;
	}

	if (arizona->pdata.reset) {
		/* Start out with /RESET low to put the chip into reset */
		ret = gpio_request_one(arizona->pdata.reset,
				       GPIOF_DIR_OUT | GPIOF_INIT_LOW,
				       "arizona /RESET");
		if (ret != 0) {
			dev_err(dev, "Failed to request /RESET: %d\n", ret);
			goto err_dcvdd;
		}
	}

	ret = regulator_bulk_enable(arizona->num_core_supplies,
				    arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to enable core supplies: %d\n",
			ret);
		goto err_dcvdd;
	}

	ret = regulator_enable(arizona->dcvdd);
	if (ret != 0) {
		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
		goto err_enable;
	}

	if (arizona->pdata.reset) {
		gpio_set_value_cansleep(arizona->pdata.reset, 1);
		msleep(1);
	}

	regcache_cache_only(arizona->regmap, false);

	/* Verify that this is a chip we know about */
	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(dev, "Failed to read ID register: %d\n", ret);
		goto err_reset;
	}

	switch (reg) {
	case 0x5102:
	case 0x5110:
	case 0x8997:
		break;
	default:
		dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
		goto err_reset;
	}

	/* If we have a /RESET GPIO we'll already be reset */
	if (!arizona->pdata.reset) {
		regcache_mark_dirty(arizona->regmap);

		ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
		if (ret != 0) {
			dev_err(dev, "Failed to reset device: %d\n", ret);
			goto err_reset;
		}

		msleep(1);

		ret = regcache_sync(arizona->regmap);
		if (ret != 0) {
			dev_err(dev, "Failed to sync device: %d\n", ret);
			goto err_reset;
		}
	}

	/* Ensure device startup is complete */
	switch (arizona->type) {
	case WM5102:
		ret = regmap_read(arizona->regmap, 0x19, &val);
		if (ret != 0)
			dev_err(dev,
				"Failed to check write sequencer state: %d\n",
				ret);
		else if (val & 0x01)
			break;
		/* Fall through */
	default:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0) {
			dev_err(arizona->dev,
				"Device failed initial boot: %d\n", ret);
			goto err_reset;
		}
		break;
	}

	/* Read the device ID information & do device specific stuff */
	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(dev, "Failed to read ID register: %d\n", ret);
		goto err_reset;
	}

	ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
			  &arizona->rev);
	if (ret != 0) {
		dev_err(dev, "Failed to read revision register: %d\n", ret);
		goto err_reset;
	}
	arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;

	switch (reg) {
#ifdef CONFIG_MFD_WM5102
	case 0x5102:
		type_name = "WM5102";
		if (arizona->type != WM5102) {
			dev_err(arizona->dev, "WM5102 registered as %d\n",
				arizona->type);
			arizona->type = WM5102;
		}
		apply_patch = wm5102_patch;
		arizona->rev &= 0x7;
		break;
#endif
#ifdef CONFIG_MFD_WM5110
	case 0x5110:
		type_name = "WM5110";
		if (arizona->type != WM5110) {
			dev_err(arizona->dev, "WM5110 registered as %d\n",
				arizona->type);
			arizona->type = WM5110;
		}
		apply_patch = wm5110_patch;
		break;
#endif
#ifdef CONFIG_MFD_WM8997
	case 0x8997:
		type_name = "WM8997";
		if (arizona->type != WM8997) {
			dev_err(arizona->dev, "WM8997 registered as %d\n",
				arizona->type);
			arizona->type = WM8997;
		}
		apply_patch = wm8997_patch;
		break;
#endif
	default:
		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
		goto err_reset;
	}

	dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');

	if (apply_patch) {
		ret = apply_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err_reset;
		}

		switch (arizona->type) {
		case WM5102:
			ret = arizona_apply_hardware_patch(arizona);
			if (ret != 0) {
				dev_err(arizona->dev,
					"Failed to apply hardware patch: %d\n",
					ret);
				goto err_reset;
			}
			break;
		default:
			break;
		}
	}

	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
		if (!arizona->pdata.gpio_defaults[i])
			continue;

		regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
			     arizona->pdata.gpio_defaults[i]);
	}

	pm_runtime_set_autosuspend_delay(arizona->dev, 100);
	pm_runtime_use_autosuspend(arizona->dev);
	pm_runtime_enable(arizona->dev);

	/* Chip default */
	if (!arizona->pdata.clk32k_src)
		arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;

	switch (arizona->pdata.clk32k_src) {
	case ARIZONA_32KZ_MCLK1:
	case ARIZONA_32KZ_MCLK2:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK,
				   arizona->pdata.clk32k_src - 1);
		arizona_clk32k_enable(arizona);
		break;
	case ARIZONA_32KZ_NONE:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK, 2);
		break;
	default:
		dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
			arizona->pdata.clk32k_src);
		ret = -EINVAL;
		goto err_reset;
	}

	for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
		if (!arizona->pdata.micbias[i].mV &&
		    !arizona->pdata.micbias[i].bypass)
			continue;

		/* Apply default for bypass mode */
		if (!arizona->pdata.micbias[i].mV)
			arizona->pdata.micbias[i].mV = 2800;

		val = (arizona->pdata.micbias[i].mV - 1500) / 100;

		val <<= ARIZONA_MICB1_LVL_SHIFT;

		if (arizona->pdata.micbias[i].ext_cap)
			val |= ARIZONA_MICB1_EXT_CAP;

		if (arizona->pdata.micbias[i].discharge)
			val |= ARIZONA_MICB1_DISCH;

		if (arizona->pdata.micbias[i].soft_start)
			val |= ARIZONA_MICB1_RATE;

		if (arizona->pdata.micbias[i].bypass)
			val |= ARIZONA_MICB1_BYPASS;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_MIC_BIAS_CTRL_1 + i,
				   ARIZONA_MICB1_LVL_MASK |
				   ARIZONA_MICB1_DISCH |
				   ARIZONA_MICB1_BYPASS |
				   ARIZONA_MICB1_RATE, val);
	}

	for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
		/* Default for both is 0 so noop with defaults */
		val = arizona->pdata.dmic_ref[i]
			<< ARIZONA_IN1_DMIC_SUP_SHIFT;
		val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_IN1L_CONTROL + (i * 8),
				   ARIZONA_IN1_DMIC_SUP_MASK |
				   ARIZONA_IN1_MODE_MASK, val);
	}

	for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
		/* Default is 0 so noop with defaults */
		if (arizona->pdata.out_mono[i])
			val = ARIZONA_OUT1_MONO;
		else
			val = 0;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
				   ARIZONA_OUT1_MONO, val);
	}

	for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
		if (arizona->pdata.spk_mute[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
					   ARIZONA_SPK1_MUTE_ENDIAN_MASK |
					   ARIZONA_SPK1_MUTE_SEQ1_MASK,
					   arizona->pdata.spk_mute[i]);

		if (arizona->pdata.spk_fmt[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
					   ARIZONA_SPK1_FMT_MASK,
					   arizona->pdata.spk_fmt[i]);
	}

	/* Set up for interrupts */
	ret = arizona_irq_init(arizona);
	if (ret != 0)
		goto err_reset;

	arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
			    arizona_clkgen_err, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
			    arizona_overclocked, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
			    arizona_underclocked, arizona);

	switch (arizona->type) {
	case WM5102:
		ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
		break;
	case WM5110:
		ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
				      ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
		break;
	case WM8997:
		ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
				      ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
		break;
	}

	if (ret != 0) {
		dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
		goto err_irq;
	}

#ifdef CONFIG_PM_RUNTIME
	regulator_disable(arizona->dcvdd);
#endif

	return 0;

err_irq:
	arizona_irq_exit(arizona);
err_reset:
	if (arizona->pdata.reset) {
		gpio_set_value_cansleep(arizona->pdata.reset, 0);
		gpio_free(arizona->pdata.reset);
	}
	regulator_disable(arizona->dcvdd);
err_enable:
	regulator_bulk_disable(arizona->num_core_supplies,
			       arizona->core_supplies);
err_dcvdd:
	regulator_put(arizona->dcvdd);
err_early:
	mfd_remove_devices(dev);
	return ret;
}
Esempio n. 11
0
static int wm9081_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
{
	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;

	case SND_SOC_BIAS_PREPARE:
		
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_SEL_MASK, 0x2);

		
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_STBY_BIAS_ENA, 0);
		break;

	case SND_SOC_BIAS_STANDBY:
		
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
			regcache_cache_only(wm9081->regmap, false);
			regcache_sync(wm9081->regmap);

			
			snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
					    WM9081_LINEOUT_DISCH, 0);

			
			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
					    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
					    WM9081_BIAS_SRC | WM9081_BIAS_ENA);

			
			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
					    WM9081_VMID_RAMP |
					    WM9081_VMID_SEL_MASK,
					    WM9081_VMID_RAMP | 0x6);

			mdelay(100);

			
			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
					    WM9081_VMID_RAMP, 0);

			
			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
					    WM9081_BIAS_SRC, 0);
		}

		
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_SEL_MASK, 0x04);

		
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_STBY_BIAS_ENA,
				    WM9081_STBY_BIAS_ENA);
		break;

	case SND_SOC_BIAS_OFF:
		
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
				    WM9081_BIAS_SRC);

		
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
				    WM9081_VMID_RAMP);

		
		snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
				    WM9081_LINEOUT_DISCH,
				    WM9081_LINEOUT_DISCH);

		regcache_cache_only(wm9081->regmap, true);
		break;
	}

	codec->dapm.bias_level = level;

	return 0;
}
Esempio n. 12
0
static int tegra30_ahub_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct tegra30_ahub_soc_data *soc_data;
	struct reset_control *rst;
	int i;
	struct resource *res0, *res1;
	void __iomem *regs_apbif, *regs_ahub;
	int ret = 0;

	if (ahub)
		return -ENODEV;

	match = of_match_device(tegra30_ahub_of_match, &pdev->dev);
	if (!match)
		return -EINVAL;
	soc_data = match->data;

	/*
	 * The AHUB hosts a register bus: the "configlink". For this to
	 * operate correctly, all devices on this bus must be out of reset.
	 * Ensure that here.
	 */
	for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) {
		if (!(configlink_mods[i].mod_list_mask &
					soc_data->mod_list_mask))
			continue;

		rst = reset_control_get_exclusive(&pdev->dev,
						  configlink_mods[i].rst_name);
		if (IS_ERR(rst)) {
			dev_err(&pdev->dev, "Can't get reset %s\n",
				configlink_mods[i].rst_name);
			ret = PTR_ERR(rst);
			return ret;
		}

		ret = reset_control_deassert(rst);
		reset_control_put(rst);
		if (ret)
			return ret;
	}

	ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
			    GFP_KERNEL);
	if (!ahub)
		return -ENOMEM;
	dev_set_drvdata(&pdev->dev, ahub);

	ahub->soc_data = soc_data;
	ahub->dev = &pdev->dev;

	ahub->clk_d_audio = devm_clk_get(&pdev->dev, "d_audio");
	if (IS_ERR(ahub->clk_d_audio)) {
		dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n");
		ret = PTR_ERR(ahub->clk_d_audio);
		return ret;
	}

	ahub->clk_apbif = devm_clk_get(&pdev->dev, "apbif");
	if (IS_ERR(ahub->clk_apbif)) {
		dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n");
		ret = PTR_ERR(ahub->clk_apbif);
		return ret;
	}

	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs_apbif = devm_ioremap_resource(&pdev->dev, res0);
	if (IS_ERR(regs_apbif))
		return PTR_ERR(regs_apbif);

	ahub->apbif_addr = res0->start;

	ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif,
					&tegra30_ahub_apbif_regmap_config);
	if (IS_ERR(ahub->regmap_apbif)) {
		dev_err(&pdev->dev, "apbif regmap init failed\n");
		ret = PTR_ERR(ahub->regmap_apbif);
		return ret;
	}
	regcache_cache_only(ahub->regmap_apbif, true);

	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	regs_ahub = devm_ioremap_resource(&pdev->dev, res1);
	if (IS_ERR(regs_ahub))
		return PTR_ERR(regs_ahub);

	ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub,
					&tegra30_ahub_ahub_regmap_config);
	if (IS_ERR(ahub->regmap_ahub)) {
		dev_err(&pdev->dev, "ahub regmap init failed\n");
		ret = PTR_ERR(ahub->regmap_ahub);
		return ret;
	}
	regcache_cache_only(ahub->regmap_ahub, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_ahub_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

	return 0;

err_pm_disable:
	pm_runtime_disable(&pdev->dev);

	return ret;
}
Esempio n. 13
0
static int wm8993_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
{
	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
	int ret;

	wm_hubs_set_bias_level(codec, level);

	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_PREPARE:
		/* VMID=2*40k */
		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
				    WM8993_VMID_SEL_MASK, 0x2);
		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
				    WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
		break;

	case SND_SOC_BIAS_STANDBY:
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
			ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
						    wm8993->supplies);
			if (ret != 0)
				return ret;

			regcache_cache_only(wm8993->regmap, false);
			regcache_sync(wm8993->regmap);

			wm_hubs_vmid_ena(codec);

			/* Bring up VMID with fast soft start */
			snd_soc_update_bits(codec, WM8993_ANTIPOP2,
					    WM8993_STARTUP_BIAS_ENA |
					    WM8993_VMID_BUF_ENA |
					    WM8993_VMID_RAMP_MASK |
					    WM8993_BIAS_SRC,
					    WM8993_STARTUP_BIAS_ENA |
					    WM8993_VMID_BUF_ENA |
					    WM8993_VMID_RAMP_MASK |
					    WM8993_BIAS_SRC);

			/* If either line output is single ended we
			 * need the VMID buffer */
			if (!wm8993->pdata.lineout1_diff ||
			    !wm8993->pdata.lineout2_diff)
				snd_soc_update_bits(codec, WM8993_ANTIPOP1,
						 WM8993_LINEOUT_VMID_BUF_ENA,
						 WM8993_LINEOUT_VMID_BUF_ENA);

			/* VMID=2*40k */
			snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
					    WM8993_VMID_SEL_MASK |
					    WM8993_BIAS_ENA,
					    WM8993_BIAS_ENA | 0x2);
			msleep(32);

			/* Switch to normal bias */
			snd_soc_update_bits(codec, WM8993_ANTIPOP2,
					    WM8993_BIAS_SRC |
					    WM8993_STARTUP_BIAS_ENA, 0);
		}

		/* VMID=2*240k */
		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
				    WM8993_VMID_SEL_MASK, 0x4);

		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
				    WM8993_TSHUT_ENA, 0);
		break;

	case SND_SOC_BIAS_OFF:
		snd_soc_update_bits(codec, WM8993_ANTIPOP1,
				    WM8993_LINEOUT_VMID_BUF_ENA, 0);

		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
				    WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
				    0);

		snd_soc_update_bits(codec, WM8993_ANTIPOP2,
				    WM8993_STARTUP_BIAS_ENA |
				    WM8993_VMID_BUF_ENA |
				    WM8993_VMID_RAMP_MASK |
				    WM8993_BIAS_SRC, 0);

		regcache_cache_only(wm8993->regmap, true);
		regcache_mark_dirty(wm8993->regmap);

		regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
				       wm8993->supplies);
		break;
	}

	codec->dapm.bias_level = level;

	return 0;
}
Esempio n. 14
0
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra30_i2s *i2s;
	const struct of_device_id *match;
	u32 cif_ids[2];
	struct resource *mem, *memregion;
	void __iomem *regs;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	match = of_match_device(tegra30_i2s_of_match, &pdev->dev);
	if (!match) {
		dev_err(&pdev->dev, "Error: No device match found\n");
		ret = -ENODEV;
		goto err;
	}
	i2s->soc_data = (struct tegra30_i2s_soc_data *)match->data;

	i2s->dai = tegra30_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	ret = of_property_read_u32_array(pdev->dev.of_node,
					 "nvidia,ahub-cif-ids", cif_ids,
					 ARRAY_SIZE(cif_ids));
	if (ret < 0)
		goto err;

	i2s->playback_i2s_cif = cif_ids[0];
	i2s->capture_i2s_cif = cif_ids[1];

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra30_i2s_regmap_config);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(i2s->regmap);
		goto err_clk_put;
	}
	regcache_cache_only(i2s->regmap, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_i2s_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->playback_dma_data.maxburst = 4;
	ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
					    i2s->playback_dma_chan,
					    sizeof(i2s->playback_dma_chan),
					    &i2s->playback_dma_data.addr);
	if (ret) {
		dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
		goto err_suspend;
	}
	ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
					     i2s->playback_fifo_cif);
	if (ret) {
		dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
		goto err_free_tx_fifo;
	}

	i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->capture_dma_data.maxburst = 4;
	ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
					    i2s->capture_dma_chan,
					    sizeof(i2s->capture_dma_chan),
					    &i2s->capture_dma_data.addr);
	if (ret) {
		dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
		goto err_unroute_tx_fifo;
	}
	ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
					     i2s->capture_i2s_cif);
	if (ret) {
		dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
		goto err_free_rx_fifo;
	}

	ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
				   &i2s->dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_unroute_rx_fifo;
	}

	ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
				&i2s->dma_config, i2s->playback_dma_chan,
				i2s->capture_dma_chan);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_component;
	}

	return 0;

err_unregister_component:
	snd_soc_unregister_component(&pdev->dev);
err_unroute_rx_fifo:
	tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
err_free_rx_fifo:
	tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
err_unroute_tx_fifo:
	tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
err_free_tx_fifo:
	tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		tegra30_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}
Esempio n. 15
0
static int wm8994_suspend(struct device *dev)
{
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	/* Don't actually go through with the suspend if the CODEC is
	 * still active (eg, for audio passthrough from CP. */
	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & WM8994_VMID_SEL_MASK) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
			  WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
			  WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
			  WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
			  WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	switch (wm8994->type) {
	case WM8958:
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
		if (ret < 0) {
			dev_err(dev, "Failed to read power status: %d\n", ret);
		} else if (ret & WM8958_MICD_ENA) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	switch (wm8994->type) {
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
		if (ret < 0) {
			dev_err(dev, "Failed to read jackdet: %d\n", ret);
		} else if (ret & WM1811_JACKDET_MODE_MASK) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	switch (wm8994->type) {
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
		if (ret < 0) {
			dev_err(dev, "Failed to read jackdet: %d\n", ret);
		} else if (ret & WM1811_JACKDET_MODE_MASK) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	/* Disable LDO pulldowns while the device is suspended if we
	 * don't know that something will be driving them. */
	if (!wm8994->ldo_ena_always_driven)
		wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);

	/* Explicitly put the device into reset in case regulators
	 * don't get disabled in order to ensure consistent restart.
	 */
	wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
			 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));

	regcache_cache_only(wm8994->regmap, true);
	regcache_mark_dirty(wm8994->regmap);

	wm8994->suspended = true;

	ret = regulator_bulk_disable(wm8994->num_supplies,
				     wm8994->supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to disable supplies: %d\n", ret);
		return ret;
	}

	return 0;
}
Esempio n. 16
0
static int wm9081_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
{
	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;

	case SND_SOC_BIAS_PREPARE:
		/* VMID=2*40k */
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_SEL_MASK, 0x2);

		/* Normal bias current */
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_STBY_BIAS_ENA, 0);
		break;

	case SND_SOC_BIAS_STANDBY:
		/* Initial cold start */
		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
			regcache_cache_only(wm9081->regmap, false);
			regcache_sync(wm9081->regmap);

			/* Disable LINEOUT discharge */
			snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
					    WM9081_LINEOUT_DISCH, 0);

			/* Select startup bias source */
			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
					    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
					    WM9081_BIAS_SRC | WM9081_BIAS_ENA);

			/* VMID 2*4k; Soft VMID ramp enable */
			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
					    WM9081_VMID_RAMP |
					    WM9081_VMID_SEL_MASK,
					    WM9081_VMID_RAMP | 0x6);

			mdelay(100);

			/* Normal bias enable & soft start off */
			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
					    WM9081_VMID_RAMP, 0);

			/* Standard bias source */
			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
					    WM9081_BIAS_SRC, 0);
		}

		/* VMID 2*240k */
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_SEL_MASK, 0x04);

		/* Standby bias current on */
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_STBY_BIAS_ENA,
				    WM9081_STBY_BIAS_ENA);
		break;

	case SND_SOC_BIAS_OFF:
		/* Startup bias source and disable bias */
		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
				    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
				    WM9081_BIAS_SRC);

		/* Disable VMID with soft ramping */
		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
				    WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
				    WM9081_VMID_RAMP);

		/* Actively discharge LINEOUT */
		snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
				    WM9081_LINEOUT_DISCH,
				    WM9081_LINEOUT_DISCH);

		regcache_cache_only(wm9081->regmap, true);
		break;
	}

	return 0;
}
Esempio n. 17
0
int twl6040_power(struct twl6040 *twl6040, int on)
{
	int ret = 0;

	mutex_lock(&twl6040->mutex);

	if (on) {
		/* already powered-up */
		if (twl6040->power_count++)
			goto out;

		clk_prepare_enable(twl6040->clk32k);

		/* Allow writes to the chip */
		regcache_cache_only(twl6040->regmap, false);

		if (gpio_is_valid(twl6040->audpwron)) {
			/* use automatic power-up sequence */
			ret = twl6040_power_up_automatic(twl6040);
			if (ret) {
				twl6040->power_count = 0;
				goto out;
			}
		} else {
			/* use manual power-up sequence */
			ret = twl6040_power_up_manual(twl6040);
			if (ret) {
				twl6040->power_count = 0;
				goto out;
			}
		}

		/* Sync with the HW */
		regcache_sync(twl6040->regmap);

		/* Default PLL configuration after power up */
		twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
		twl6040->sysclk = 19200000;
		twl6040->mclk = 32768;
	} else {
		/* already powered-down */
		if (!twl6040->power_count) {
			dev_err(twl6040->dev,
				"device is already powered-off\n");
			ret = -EPERM;
			goto out;
		}

		if (--twl6040->power_count)
			goto out;

		if (gpio_is_valid(twl6040->audpwron)) {
			/* use AUDPWRON line */
			gpio_set_value(twl6040->audpwron, 0);

			/* power-down sequence latency */
			usleep_range(500, 700);
		} else {
			/* use manual power-down sequence */
			twl6040_power_down_manual(twl6040);
		}

		/* Set regmap to cache only and mark it as dirty */
		regcache_cache_only(twl6040->regmap, true);
		regcache_mark_dirty(twl6040->regmap);

		twl6040->sysclk = 0;
		twl6040->mclk = 0;

		clk_disable_unprepare(twl6040->clk32k);
	}

out:
	mutex_unlock(&twl6040->mutex);
	return ret;
}
Esempio n. 18
0
static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
				       const struct i2c_device_id *id)
{
	struct cs42l73_private *cs42l73;
	int ret;
	unsigned int devid = 0;
	unsigned int reg;

	cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private),
			       GFP_KERNEL);
	if (!cs42l73) {
		dev_err(&i2c_client->dev, "could not allocate codec\n");
		return -ENOMEM;
	}

	i2c_set_clientdata(i2c_client, cs42l73);

	cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap);
	if (IS_ERR(cs42l73->regmap)) {
		ret = PTR_ERR(cs42l73->regmap);
		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
		goto err;
	}
	/* initialize codec */
	ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg);
	devid = (reg & 0xFF) << 12;

	ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, &reg);
	devid |= (reg & 0xFF) << 4;

	ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, &reg);
	devid |= (reg & 0xF0) >> 4;


	if (devid != CS42L73_DEVID) {
		ret = -ENODEV;
		dev_err(&i2c_client->dev,
			"CS42L73 Device ID (%X). Expected %X\n",
			devid, CS42L73_DEVID);
		goto err_regmap;
	}

	ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
		goto err_regmap;
	}

	dev_info(&i2c_client->dev,
		 "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);

	regcache_cache_only(cs42l73->regmap, true);

	ret =  snd_soc_register_codec(&i2c_client->dev,
			&soc_codec_dev_cs42l73, cs42l73_dai,
			ARRAY_SIZE(cs42l73_dai));
	if (ret < 0)
		goto err_regmap;
	return 0;

err_regmap:
	regmap_exit(cs42l73->regmap);

err:
	return ret;
}
Esempio n. 19
0
static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
{
	struct mtk_base_afe *afe;
	struct mt8183_afe_private *afe_priv;
	struct device *dev;
	int i, irq_id, ret;

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

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

	afe_priv = afe->platform_priv;
	afe->dev = &pdev->dev;
	dev = afe->dev;

	/* initial audio related clock */
	ret = mt8183_init_clock(afe);
	if (ret) {
		dev_err(dev, "init clock error\n");
		return ret;
	}

	pm_runtime_enable(dev);

	/* regmap init */
	afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
	if (IS_ERR(afe->regmap)) {
		dev_err(dev, "could not get regmap from parent\n");
		return PTR_ERR(afe->regmap);
	}
	ret = regmap_attach_dev(dev, afe->regmap, &mt8183_afe_regmap_config);
	if (ret) {
		dev_warn(dev, "regmap_attach_dev fail, ret %d\n", ret);
		return ret;
	}

	/* enable clock for regcache get default value from hw */
	afe_priv->pm_runtime_bypass_reg_ctl = true;
	pm_runtime_get_sync(&pdev->dev);

	ret = regmap_reinit_cache(afe->regmap, &mt8183_afe_regmap_config);
	if (ret) {
		dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret);
		return ret;
	}

	pm_runtime_put_sync(&pdev->dev);
	afe_priv->pm_runtime_bypass_reg_ctl = false;

	regcache_cache_only(afe->regmap, true);
	regcache_mark_dirty(afe->regmap);

	pm_runtime_get_sync(&pdev->dev);

	/* init memif */
	afe->memif_size = MT8183_MEMIF_NUM;
	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
				  GFP_KERNEL);
	if (!afe->memif)
		return -ENOMEM;

	for (i = 0; i < afe->memif_size; i++) {
		afe->memif[i].data = &memif_data[i];
		afe->memif[i].irq_usage = -1;
	}

	afe->memif[MT8183_MEMIF_HDMI].irq_usage = MT8183_IRQ_8;
	afe->memif[MT8183_MEMIF_HDMI].const_irq = 1;

	mutex_init(&afe->irq_alloc_lock);

	/* init memif */
	/* irq initialize */
	afe->irqs_size = MT8183_IRQ_NUM;
	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
				 GFP_KERNEL);
	if (!afe->irqs)
		return -ENOMEM;

	for (i = 0; i < afe->irqs_size; i++)
		afe->irqs[i].irq_data = &irq_data[i];

	/* request irq */
	irq_id = platform_get_irq(pdev, 0);
	if (!irq_id) {
		dev_err(dev, "%pOFn no irq found\n", dev->of_node);
		return -ENXIO;
	}
	ret = devm_request_irq(dev, irq_id, mt8183_afe_irq_handler,
			       IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
	if (ret) {
		dev_err(dev, "could not request_irq for asys-isr\n");
		return ret;
	}

	/* init sub_dais */
	INIT_LIST_HEAD(&afe->sub_dais);

	for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
		ret = dai_register_cbs[i](afe);
		if (ret) {
			dev_warn(afe->dev, "dai register i %d fail, ret %d\n",
				 i, ret);
			return ret;
		}
	}

	/* init dai_driver and component_driver */
	ret = mtk_afe_combine_sub_dai(afe);
	if (ret) {
		dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
			 ret);
		return ret;
	}

	afe->mtk_afe_hardware = &mt8183_afe_hardware;
	afe->memif_fs = mt8183_memif_fs;
	afe->irq_fs = mt8183_irq_fs;

	afe->runtime_resume = mt8183_afe_runtime_resume;
	afe->runtime_suspend = mt8183_afe_runtime_suspend;

	/* register component */
	ret = devm_snd_soc_register_component(&pdev->dev,
					      &mt8183_afe_component,
					      NULL, 0);
	if (ret) {
		dev_warn(dev, "err_platform\n");
		return ret;
	}

	ret = devm_snd_soc_register_component(afe->dev,
					      &mt8183_afe_pcm_dai_component,
					      afe->dai_drivers,
					      afe->num_dai_drivers);
	if (ret) {
		dev_warn(dev, "err_dai_component\n");
		return ret;
	}

	return ret;
}
Esempio n. 20
0
int __devinit arizona_dev_init(struct arizona *arizona)
{
	struct device *dev = arizona->dev;
	const char *type_name;
	unsigned int reg, val;
	int (*apply_patch)(struct arizona *) = NULL;
	int ret, i;

	dev_set_drvdata(arizona->dev, arizona);
	mutex_init(&arizona->clk_lock);

	if (dev_get_platdata(arizona->dev))
		memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
		       sizeof(arizona->pdata));

	regcache_cache_only(arizona->regmap, true);

	switch (arizona->type) {
	case WM5102:
	case WM5110:
		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
			arizona->core_supplies[i].supply
				= wm5102_core_supplies[i];
		arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
		break;
	default:
		dev_err(arizona->dev, "Unknown device type %d\n",
			arizona->type);
		return -EINVAL;
	}

	ret = mfd_add_devices(arizona->dev, -1, early_devs,
			      ARRAY_SIZE(early_devs), NULL, 0);
	if (ret != 0) {
		dev_err(dev, "Failed to add early children: %d\n", ret);
		return ret;
	}

	ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
				      arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to request core supplies: %d\n",
			ret);
		goto err_early;
	}

	arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
	if (IS_ERR(arizona->dcvdd)) {
		ret = PTR_ERR(arizona->dcvdd);
		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
		goto err_early;
	}

	ret = regulator_bulk_enable(arizona->num_core_supplies,
				    arizona->core_supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to enable core supplies: %d\n",
			ret);
		goto err_early;
	}

	ret = regulator_enable(arizona->dcvdd);
	if (ret != 0) {
		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
		goto err_enable;
	}

	if (arizona->pdata.control_init_time)
		msleep(arizona->pdata.control_init_time);

	if (arizona->pdata.reset) {
		/* Start out with /RESET low to put the chip into reset */
		ret = gpio_request_one(arizona->pdata.reset,
				       GPIOF_DIR_OUT | GPIOF_INIT_LOW,
				       "arizona /RESET");
		if (ret != 0) {
			dev_err(dev, "Failed to request /RESET: %d\n", ret);
			goto err_dcvdd;
		}

		gpio_set_value_cansleep(arizona->pdata.reset, 1);
	}

	regcache_cache_only(arizona->regmap, false);

	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(dev, "Failed to read ID register: %d\n", ret);
		goto err_reset;
	}

	ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
			  &arizona->rev);
	if (ret != 0) {
		dev_err(dev, "Failed to read revision register: %d\n", ret);
		goto err_reset;
	}
	arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;

	switch (reg) {
#ifdef CONFIG_MFD_WM5102
	case 0x5102:
		type_name = "WM5102";
		if (arizona->type != WM5102) {
			dev_err(arizona->dev, "WM5102 registered as %d\n",
				arizona->type);
			arizona->type = WM5102;
		}
		apply_patch = wm5102_patch;
		break;
#endif
#ifdef CONFIG_MFD_WM5110
	case 0x5110:
		type_name = "WM5110";
		if (arizona->type != WM5110) {
			dev_err(arizona->dev, "WM5110 registered as %d\n",
				arizona->type);
			arizona->type = WM5110;
		}
		apply_patch = wm5110_patch;
		break;
#endif
	default:
		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
		goto err_reset;
	}

	dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');

	/* If we have a /RESET GPIO we'll already be reset */
	if (!arizona->pdata.reset) {
		ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
		if (ret != 0) {
			dev_err(dev, "Failed to reset device: %d\n", ret);
			goto err_reset;
		}
	}

	ret = arizona_wait_for_boot(arizona);
	if (ret != 0) {
		dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
		goto err_reset;
	}

	if (apply_patch) {
		ret = apply_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err_reset;
		}
	}

	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
		if (!arizona->pdata.gpio_defaults[i])
			continue;

		regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
			     arizona->pdata.gpio_defaults[i]);
	}

	pm_runtime_enable(arizona->dev);

	/* Chip default */
	if (!arizona->pdata.clk32k_src)
		arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;

	switch (arizona->pdata.clk32k_src) {
	case ARIZONA_32KZ_MCLK1:
	case ARIZONA_32KZ_MCLK2:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK,
				   arizona->pdata.clk32k_src - 1);
		break;
	case ARIZONA_32KZ_NONE:
		regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
				   ARIZONA_CLK_32K_SRC_MASK, 2);
		break;
	default:
		dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
			arizona->pdata.clk32k_src);
		ret = -EINVAL;
		goto err_reset;
	}

	for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
		if (!arizona->pdata.micbias[i].mV &&
		    !arizona->pdata.micbias[i].bypass)
			continue;

		/* Apply default for bypass mode */
		if (!arizona->pdata.micbias[i].mV)
			arizona->pdata.micbias[i].mV = 2800;

		val = (arizona->pdata.micbias[i].mV - 1500) / 100;

		val <<= ARIZONA_MICB1_LVL_SHIFT;

		if (arizona->pdata.micbias[i].ext_cap)
			val |= ARIZONA_MICB1_EXT_CAP;

		if (arizona->pdata.micbias[i].discharge)
			val |= ARIZONA_MICB1_DISCH;

		if (arizona->pdata.micbias[i].fast_start)
			val |= ARIZONA_MICB1_RATE;

		if (arizona->pdata.micbias[i].bypass)
			val |= ARIZONA_MICB1_BYPASS;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_MIC_BIAS_CTRL_1 + i,
				   ARIZONA_MICB1_LVL_MASK |
				   ARIZONA_MICB1_DISCH |
				   ARIZONA_MICB1_BYPASS |
				   ARIZONA_MICB1_RATE, val);
	}

	for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
		/* Default for both is 0 so noop with defaults */
		val = arizona->pdata.dmic_ref[i]
			<< ARIZONA_IN1_DMIC_SUP_SHIFT;
		val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_IN1L_CONTROL + (i * 8),
				   ARIZONA_IN1_DMIC_SUP_MASK |
				   ARIZONA_IN1_MODE_MASK, val);
	}

	for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
		/* Default is 0 so noop with defaults */
		if (arizona->pdata.out_mono[i])
			val = ARIZONA_OUT1_MONO;
		else
			val = 0;

		regmap_update_bits(arizona->regmap,
				   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
				   ARIZONA_OUT1_MONO, val);
	}

	for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
		if (arizona->pdata.spk_mute[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
					   ARIZONA_SPK1_MUTE_ENDIAN_MASK |
					   ARIZONA_SPK1_MUTE_SEQ1_MASK,
					   arizona->pdata.spk_mute[i]);

		if (arizona->pdata.spk_fmt[i])
			regmap_update_bits(arizona->regmap,
					   ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
					   ARIZONA_SPK1_FMT_MASK,
					   arizona->pdata.spk_fmt[i]);
	}

	/* set virtual IRQs */
	arizona->virq[0] = arizona->pdata.irq_base;
	arizona->virq[1] = arizona->pdata.irq_base + ARIZONA_NUM_IRQ;

	switch (arizona->pdata.mic_spk_clamp) {
	case ARIZONA_MIC_CLAMP_SPKLN:
		regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2,
				   0x3c, 0xc);
		break;
	case ARIZONA_MIC_CLAMP_SPKLP:
		regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2,
				   0x3c, 0x1c);
		break;
	case ARIZONA_MIC_CLAMP_SPKRN:
		regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3,
				   0x3c, 0xc);
		break;
	case ARIZONA_MIC_CLAMP_SPKRP:
		regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3,
				   0x3c, 0x1c);
		break;
	default:
		break;
	}

	/* Set up for interrupts */
	ret = arizona_irq_init(arizona);
	if (ret != 0)
		goto err_reset;

	arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
			    arizona_clkgen_err, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
			    arizona_overclocked, arizona);
	arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
			    arizona_underclocked, arizona);

	switch (arizona->type) {
	case WM5102:
		ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
				      ARRAY_SIZE(wm5102_devs), NULL, 0);
		break;
	case WM5110:
		ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
				      ARRAY_SIZE(wm5110_devs), NULL, 0);
		break;
	}

	if (ret != 0) {
		dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
		goto err_irq;
	}

	if (arizona->pdata.init_done)
		arizona->pdata.init_done();

#ifdef CONFIG_PM_RUNTIME
	regulator_disable(arizona->dcvdd);
#endif

	return 0;

err_irq:
	arizona_irq_exit(arizona);
err_reset:
	if (arizona->pdata.reset) {
		gpio_set_value_cansleep(arizona->pdata.reset, 1);
		gpio_free(arizona->pdata.reset);
	}
err_dcvdd:
	regulator_disable(arizona->dcvdd);
err_enable:
	regulator_bulk_disable(arizona->num_core_supplies,
			       arizona->core_supplies);
err_early:
	mfd_remove_devices(dev);
	return ret;
}
Esempio n. 21
0
static int arizona_runtime_resume(struct device *dev)
{
	struct arizona *arizona = dev_get_drvdata(dev);
	int ret;

	dev_dbg(arizona->dev, "Leaving AoD mode\n");

	ret = regulator_enable(arizona->dcvdd);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
		return ret;
	}

	regcache_cache_only(arizona->regmap, false);

	switch (arizona->type) {
	case WM5102:
		if (arizona->external_dcvdd) {
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1, 0);
			if (ret != 0) {
				dev_err(arizona->dev,
					"Failed to connect DCVDD: %d\n", ret);
				goto err;
			}
		}

		ret = wm5102_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err;
		}

		ret = arizona_apply_hardware_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev,
				"Failed to apply hardware patch: %d\n",
				ret);
			goto err;
		}
		break;
	default:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0) {
			goto err;
		}

		if (arizona->external_dcvdd) {
			ret = regmap_update_bits(arizona->regmap,
						 ARIZONA_ISOLATION_CONTROL,
						 ARIZONA_ISOLATE_DCVDD1, 0);
			if (ret != 0) {
				dev_err(arizona->dev,
					"Failed to connect DCVDD: %d\n", ret);
				goto err;
			}
		}
		break;
	}

	switch (arizona->type) {
	case WM5102:
		ret = wm5102_patch(arizona);
		if (ret != 0) {
			dev_err(arizona->dev, "Failed to apply patch: %d\n",
				ret);
			goto err;
		}
	default:
		break;
	}

	ret = regcache_sync(arizona->regmap);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to restore register cache\n");
		goto err;
	}

	return 0;

err:
	regcache_cache_only(arizona->regmap, true);
	regulator_disable(arizona->dcvdd);
	return ret;
}
Esempio n. 22
0
static int adau1977_power_enable(struct adau1977 *adau1977)
{
	unsigned int val;
	int ret = 0;

	if (adau1977->enabled)
		return 0;

	ret = regulator_enable(adau1977->avdd_reg);
	if (ret)
		return ret;

	if (adau1977->dvdd_reg) {
		ret = regulator_enable(adau1977->dvdd_reg);
		if (ret)
			goto err_disable_avdd;
	}

	if (adau1977->reset_gpio)
		gpiod_set_value_cansleep(adau1977->reset_gpio, 1);

	regcache_cache_only(adau1977->regmap, false);

	if (adau1977->switch_mode)
		adau1977->switch_mode(adau1977->dev);

	ret = adau1977_reset(adau1977);
	if (ret)
		goto err_disable_dvdd;

	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
		ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP);
	if (ret)
		goto err_disable_dvdd;

	ret = regcache_sync(adau1977->regmap);
	if (ret)
		goto err_disable_dvdd;

	/*
	 * The PLL register is not affected by the software reset. It is
	 * possible that the value of the register was changed to the
	 * default value while we were in cache only mode. In this case
	 * regcache_sync will skip over it and we have to manually sync
	 * it.
	 */
	ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val);
	if (ret)
		goto err_disable_dvdd;

	if (val == 0x41) {
		regcache_cache_bypass(adau1977->regmap, true);
		ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL,
			0x41);
		if (ret)
			goto err_disable_dvdd;
		regcache_cache_bypass(adau1977->regmap, false);
	}

	adau1977->enabled = true;

	return ret;

err_disable_dvdd:
	if (adau1977->dvdd_reg)
		regulator_disable(adau1977->dvdd_reg);
err_disable_avdd:
		regulator_disable(adau1977->avdd_reg);
	return ret;
}
Esempio n. 23
0
static int wm8993_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
{
	struct wm8993_priv *wm8993;
	unsigned int reg;
	int ret, i;

	wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv),
			      GFP_KERNEL);
	if (wm8993 == NULL)
		return -ENOMEM;

	wm8993->dev = &i2c->dev;
	init_completion(&wm8993->fll_lock);

	wm8993->regmap = devm_regmap_init_i2c(i2c, &wm8993_regmap);
	if (IS_ERR(wm8993->regmap)) {
		ret = PTR_ERR(wm8993->regmap);
		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
		return ret;
	}

	i2c_set_clientdata(i2c, wm8993);

	for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
		wm8993->supplies[i].supply = wm8993_supply_names[i];

	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies),
				 wm8993->supplies);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
		return ret;
	}

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

	ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, &reg);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
		goto err_enable;
	}

	if (reg != 0x8993) {
		dev_err(&i2c->dev, "Invalid ID register value %x\n", reg);
		ret = -EINVAL;
		goto err_enable;
	}

	ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff);
	if (ret != 0)
		goto err_enable;

	ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch,
				    ARRAY_SIZE(wm8993_regmap_patch));
	if (ret != 0)
		dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n",
			 ret);

	if (i2c->irq) {
		/* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */
		ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1,
					 WM8993_GPIO1_PD |
					 WM8993_GPIO1_SEL_MASK, 7);
		if (ret != 0)
			goto err_enable;

		ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq,
					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
					   "wm8993", wm8993);
		if (ret != 0)
			goto err_enable;

	}

	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);

	regcache_cache_only(wm8993->regmap, true);

	ret = snd_soc_register_codec(&i2c->dev,
			&soc_codec_dev_wm8993, &wm8993_dai, 1);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
		goto err_irq;
	}

	return 0;

err_irq:
	if (i2c->irq)
		free_irq(i2c->irq, wm8993);
err_enable:
	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
	return ret;
}
Esempio n. 24
0
static int wm8994_suspend(struct device *dev)
{
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & WM8994_VMID_SEL_MASK) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
			  WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
			  WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
			  WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
			  WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	switch (wm8994->type) {
	case WM8958:
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
		if (ret < 0) {
			dev_err(dev, "Failed to read power status: %d\n", ret);
		} else if (ret & WM8958_MICD_ENA) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	switch (wm8994->type) {
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
		if (ret < 0) {
			dev_err(dev, "Failed to read jackdet: %d\n", ret);
		} else if (ret & WM1811_JACKDET_MODE_MASK) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	switch (wm8994->type) {
	case WM1811:
		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
		if (ret < 0) {
			dev_err(dev, "Failed to read jackdet: %d\n", ret);
		} else if (ret & WM1811_JACKDET_MODE_MASK) {
			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
			return 0;
		}
		break;
	default:
		break;
	}

	if (!wm8994->ldo_ena_always_driven)
		wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);

	wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
			 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));

	regcache_cache_only(wm8994->regmap, true);
	regcache_mark_dirty(wm8994->regmap);

	wm8994->suspended = true;

	ret = regulator_bulk_disable(wm8994->num_supplies,
				     wm8994->supplies);
	if (ret != 0) {
		dev_err(dev, "Failed to disable supplies: %d\n", ret);
		return ret;
	}

	return 0;
}
static int tegra30_ahub_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct tegra30_ahub_soc_data *soc_data;
	struct clk *clk;
	int i;
	struct resource *res0, *res1, *region;
	u32 of_dma[2];
	void __iomem *regs_apbif, *regs_ahub;
	int ret = 0;

	if (ahub)
		return -ENODEV;

	match = of_match_device(tegra30_ahub_of_match, &pdev->dev);
	if (!match)
		return -EINVAL;
	soc_data = match->data;

	/*
	 * The AHUB hosts a register bus: the "configlink". For this to
	 * operate correctly, all devices on this bus must be out of reset.
	 * Ensure that here.
	 */
	for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
		if (!(configlink_clocks[i].clk_list_mask &
					soc_data->clk_list_mask))
			continue;
		clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name);
		if (IS_ERR(clk)) {
			dev_err(&pdev->dev, "Can't get clock %s\n",
				configlink_clocks[i].clk_name);
			ret = PTR_ERR(clk);
			goto err;
		}
		tegra_periph_reset_deassert(clk);
		clk_put(clk);
	}

	ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
			    GFP_KERNEL);
	if (!ahub) {
		dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, ahub);

	ahub->dev = &pdev->dev;

	ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio");
	if (IS_ERR(ahub->clk_d_audio)) {
		dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n");
		ret = PTR_ERR(ahub->clk_d_audio);
		goto err;
	}

	ahub->clk_apbif = clk_get(&pdev->dev, "apbif");
	if (IS_ERR(ahub->clk_apbif)) {
		dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n");
		ret = PTR_ERR(ahub->clk_apbif);
		goto err_clk_put_d_audio;
	}

	if (of_property_read_u32_array(pdev->dev.of_node,
				"nvidia,dma-request-selector",
				of_dma, 2) < 0) {
		dev_err(&pdev->dev,
			"Missing property nvidia,dma-request-selector\n");
		ret = -ENODEV;
		goto err_clk_put_d_audio;
	}
	ahub->dma_sel = of_dma[1];

	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res0) {
		dev_err(&pdev->dev, "No apbif memory resource\n");
		ret = -ENODEV;
		goto err_clk_put_apbif;
	}

	region = devm_request_mem_region(&pdev->dev, res0->start,
					 resource_size(res0), DRV_NAME);
	if (!region) {
		dev_err(&pdev->dev, "request region apbif failed\n");
		ret = -EBUSY;
		goto err_clk_put_apbif;
	}
	ahub->apbif_addr = res0->start;

	regs_apbif = devm_ioremap(&pdev->dev, res0->start,
				  resource_size(res0));
	if (!regs_apbif) {
		dev_err(&pdev->dev, "ioremap apbif failed\n");
		ret = -ENOMEM;
		goto err_clk_put_apbif;
	}

	ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif,
					&tegra30_ahub_apbif_regmap_config);
	if (IS_ERR(ahub->regmap_apbif)) {
		dev_err(&pdev->dev, "apbif regmap init failed\n");
		ret = PTR_ERR(ahub->regmap_apbif);
		goto err_clk_put_apbif;
	}
	regcache_cache_only(ahub->regmap_apbif, true);

	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res1) {
		dev_err(&pdev->dev, "No ahub memory resource\n");
		ret = -ENODEV;
		goto err_clk_put_apbif;
	}

	region = devm_request_mem_region(&pdev->dev, res1->start,
					 resource_size(res1), DRV_NAME);
	if (!region) {
		dev_err(&pdev->dev, "request region ahub failed\n");
		ret = -EBUSY;
		goto err_clk_put_apbif;
	}

	regs_ahub = devm_ioremap(&pdev->dev, res1->start,
				 resource_size(res1));
	if (!regs_ahub) {
		dev_err(&pdev->dev, "ioremap ahub failed\n");
		ret = -ENOMEM;
		goto err_clk_put_apbif;
	}

	ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub,
					&tegra30_ahub_ahub_regmap_config);
	if (IS_ERR(ahub->regmap_ahub)) {
		dev_err(&pdev->dev, "ahub regmap init failed\n");
		ret = PTR_ERR(ahub->regmap_ahub);
		goto err_clk_put_apbif;
	}
	regcache_cache_only(ahub->regmap_ahub, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_ahub_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

	return 0;

err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put_apbif:
	clk_put(ahub->clk_apbif);
err_clk_put_d_audio:
	clk_put(ahub->clk_d_audio);
	ahub = NULL;
err:
	return ret;
}
Esempio n. 26
0
int twl6040_power(struct twl6040 *twl6040, int on)
{
	int ret = 0;

	mutex_lock(&twl6040->mutex);

	if (on) {
		/* already powered-up */
		if (twl6040->power_count++)
			goto out;

		ret = clk_prepare_enable(twl6040->clk32k);
		if (ret) {
			twl6040->power_count = 0;
			goto out;
		}

		/* Allow writes to the chip */
		regcache_cache_only(twl6040->regmap, false);

		if (gpio_is_valid(twl6040->audpwron)) {
			/* use automatic power-up sequence */
			ret = twl6040_power_up_automatic(twl6040);
			if (ret) {
				clk_disable_unprepare(twl6040->clk32k);
				twl6040->power_count = 0;
				goto out;
			}
		} else {
			/* use manual power-up sequence */
			ret = twl6040_power_up_manual(twl6040);
			if (ret) {
				clk_disable_unprepare(twl6040->clk32k);
				twl6040->power_count = 0;
				goto out;
			}
		}

		/*
		 * Register access can produce errors after power-up unless we
		 * wait at least 8ms based on measurements on duovero.
		 */
		usleep_range(10000, 12000);

		/* Sync with the HW */
		ret = regcache_sync(twl6040->regmap);
		if (ret) {
			dev_err(twl6040->dev, "Failed to sync with the HW: %i\n",
				ret);
			goto out;
		}

		/* Default PLL configuration after power up */
		twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
		twl6040->sysclk_rate = 19200000;
	} else {
		/* already powered-down */
		if (!twl6040->power_count) {
			dev_err(twl6040->dev,
				"device is already powered-off\n");
			ret = -EPERM;
			goto out;
		}

		if (--twl6040->power_count)
			goto out;

		if (gpio_is_valid(twl6040->audpwron)) {
			/* use AUDPWRON line */
			gpio_set_value(twl6040->audpwron, 0);

			/* power-down sequence latency */
			usleep_range(500, 700);
		} else {
			/* use manual power-down sequence */
			twl6040_power_down_manual(twl6040);
		}

		/* Set regmap to cache only and mark it as dirty */
		regcache_cache_only(twl6040->regmap, true);
		regcache_mark_dirty(twl6040->regmap);

		twl6040->sysclk_rate = 0;

		if (twl6040->pll == TWL6040_SYSCLK_SEL_HPPLL) {
			clk_disable_unprepare(twl6040->mclk);
			twl6040->mclk_rate = 0;
		}

		clk_disable_unprepare(twl6040->clk32k);
	}

out:
	mutex_unlock(&twl6040->mutex);
	return ret;
}
Esempio n. 27
0
static int sta32x_probe(struct snd_soc_codec *codec)
{
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
	int i, ret = 0, thermal = 0;

	sta32x->codec = codec;
	sta32x->pdata = dev_get_platdata(codec->dev);

	ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
				    sta32x->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
		return ret;
	}

	/* Chip documentation explicitly requires that the reset values
	 * of reserved register bits are left untouched.
	 * Write the register default value to cache for reserved registers,
	 * so the write to the these registers are suppressed by the cache
	 * restore code when it skips writes of default registers.
	 */
	regcache_cache_only(sta32x->regmap, true);
	snd_soc_write(codec, STA32X_CONFC, 0xc2);
	snd_soc_write(codec, STA32X_CONFE, 0xc2);
	snd_soc_write(codec, STA32X_CONFF, 0x5c);
	snd_soc_write(codec, STA32X_MMUTE, 0x10);
	snd_soc_write(codec, STA32X_AUTO1, 0x60);
	snd_soc_write(codec, STA32X_AUTO3, 0x00);
	snd_soc_write(codec, STA32X_C3CFG, 0x40);
	regcache_cache_only(sta32x->regmap, false);

	/* set thermal warning adjustment and recovery */
	if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
		thermal |= STA32X_CONFA_TWAB;
	if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
		thermal |= STA32X_CONFA_TWRB;
	snd_soc_update_bits(codec, STA32X_CONFA,
			    STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
			    thermal);

	/* select output configuration  */
	snd_soc_update_bits(codec, STA32X_CONFF,
			    STA32X_CONFF_OCFG_MASK,
			    sta32x->pdata->output_conf
			    << STA32X_CONFF_OCFG_SHIFT);

	/* channel to output mapping */
	snd_soc_update_bits(codec, STA32X_C1CFG,
			    STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch1_output_mapping
			    << STA32X_CxCFG_OM_SHIFT);
	snd_soc_update_bits(codec, STA32X_C2CFG,
			    STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch2_output_mapping
			    << STA32X_CxCFG_OM_SHIFT);
	snd_soc_update_bits(codec, STA32X_C3CFG,
			    STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch3_output_mapping
			    << STA32X_CxCFG_OM_SHIFT);

	/* initialize coefficient shadow RAM with reset values */
	for (i = 4; i <= 49; i += 5)
		sta32x->coef_shadow[i] = 0x400000;
	for (i = 50; i <= 54; i++)
		sta32x->coef_shadow[i] = 0x7fffff;
	sta32x->coef_shadow[55] = 0x5a9df7;
	sta32x->coef_shadow[56] = 0x7fffff;
	sta32x->coef_shadow[59] = 0x7fffff;
	sta32x->coef_shadow[60] = 0x400000;
	sta32x->coef_shadow[61] = 0x400000;

	if (sta32x->pdata->needs_esd_watchdog)
		INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);

	sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	/* Bias level configuration will have done an extra enable */
	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);

	return 0;
}
Esempio n. 28
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;
}
Esempio n. 29
0
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra30_i2s *i2s;
	u32 cif_ids[2];
	struct resource *mem, *memregion;
	void __iomem *regs;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	i2s->dai = tegra30_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	ret = of_property_read_u32_array(pdev->dev.of_node,
					 "nvidia,ahub-cif-ids", cif_ids,
					 ARRAY_SIZE(cif_ids));
	if (ret < 0)
		goto err;

	i2s->playback_i2s_cif = cif_ids[0];
	i2s->capture_i2s_cif = cif_ids[1];

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra30_i2s_regmap_config);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(i2s->regmap);
		goto err_clk_put;
	}
	regcache_cache_only(i2s->regmap, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_i2s_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_suspend;
	}

	ret = tegra_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_dai;
	}

	return 0;

err_unregister_dai:
	snd_soc_unregister_dai(&pdev->dev);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		tegra30_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}
Esempio n. 30
0
static int max98925_suspend(struct device *dev)
{
	regcache_cache_only(max98925_data->regmapL, true);
	return 0;
}