Загрузка данных


static int sgtl5000_of_xlate_dai_id(struct snd_soc_component *component,
				    struct device_node *endpoint)
{
	/* return dai id 0, whatever the endpoint index */
	return 0;
}

static const struct snd_soc_component_driver sgtl5000_driver = {
	.probe			= sgtl5000_probe,
	.set_bias_level		= sgtl5000_set_bias_level,
	.controls		= sgtl5000_snd_controls,
	.num_controls		= ARRAY_SIZE(sgtl5000_snd_controls),
	.dapm_widgets		= sgtl5000_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(sgtl5000_dapm_widgets),
	.dapm_routes		= sgtl5000_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(sgtl5000_dapm_routes),
	.of_xlate_dai_id	= sgtl5000_of_xlate_dai_id,
	.suspend_bias_off	= 1,
	.idle_bias_on		= 1,
	.use_pmdown_time	= 1,
	.endianness		= 1,
};

static const struct regmap_config sgtl5000_regmap = {
	.reg_bits = 16,
	.val_bits = 16,
	.reg_stride = 2,

	.max_register = SGTL5000_MAX_REG_OFFSET,
	.volatile_reg = sgtl5000_volatile,
	.readable_reg = sgtl5000_readable,

	.cache_type = REGCACHE_RBTREE,
	.reg_defaults = sgtl5000_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(sgtl5000_reg_defaults),
};

/*
 * Write all the default values from sgtl5000_reg_defaults[] array into the
 * sgtl5000 registers, to make sure we always start with the sane registers
 * values as stated in the datasheet.
 *
 * Since sgtl5000 does not have a reset line, nor a reset command in software,
 * we follow this approach to guarantee we always start from the default values
 * and avoid problems like, not being able to probe after an audio playback
 * followed by a system reset or a 'reboot' command in Linux
 */
static void sgtl5000_fill_defaults(struct i2c_client *client)
{
	struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
	int i, ret, val, index;

	for (i = 0; i < ARRAY_SIZE(sgtl5000_reg_defaults); i++) {
		val = sgtl5000_reg_defaults[i].def;
		index = sgtl5000_reg_defaults[i].reg;
		ret = regmap_write(sgtl5000->regmap, index, val);
		if (ret)
			dev_err(&client->dev,
				"%s: error %d setting reg 0x%02x to 0x%04x\n",
				__func__, ret, index, val);
	}
}

static int sgtl5000_i2c_probe(struct i2c_client *client)
{
	struct sgtl5000_priv *sgtl5000;
	int ret, reg, rev;
	struct device_node *np = client->dev.of_node;
	u32 value;
	u16 ana_pwr;

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

	i2c_set_clientdata(client, sgtl5000);

	ret = sgtl5000_enable_regulators(client);
	if (ret)
		return ret;

	sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap);
	if (IS_ERR(sgtl5000->regmap)) {
		ret = PTR_ERR(sgtl5000->regmap);
		dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
		goto disable_regs;
	}

	sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
	if (IS_ERR(sgtl5000->mclk)) {
		ret = PTR_ERR(sgtl5000->mclk);
		/* Defer the probe to see if the clk will be provided later */
		if (ret == -ENOENT)
			ret = -EPROBE_DEFER;

		dev_err_probe(&client->dev, ret, "Failed to get mclock\n");

		goto disable_regs;
	}

	ret = clk_prepare_enable(sgtl5000->mclk);
	if (ret) {
		dev_err(&client->dev, "Error enabling clock %d\n", ret);
		goto disable_regs;
	}

	/* Need 8 clocks before I2C accesses */
	udelay(1);

	/* read chip information */
	ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
	if (ret) {
		dev_err(&client->dev, "Error reading chip id %d\n", ret);
		goto disable_clk;
	}

	if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
	    SGTL5000_PARTID_PART_ID) {
		dev_err(&client->dev,
			"Device with ID register %x is not a sgtl5000\n", reg);
		ret = -ENODEV;
		goto disable_clk;
	}

	rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
	dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev);
	sgtl5000->revision = rev;

	/* reconfigure the clocks in case we're using the PLL */
	ret = regmap_write(sgtl5000->regmap,
			   SGTL5000_CHIP_CLK_CTRL,
			   SGTL5000_CHIP_CLK_CTRL_DEFAULT);
	if (ret)
		dev_err(&client->dev,
			"Error %d initializing CHIP_CLK_CTRL\n", ret);

	/* Mute everything to avoid pop from the following power-up */
	ret = regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_CTRL,
			   SGTL5000_CHIP_ANA_CTRL_DEFAULT);
	if (ret) {
		dev_err(&client->dev,
			"Error %d muting outputs via CHIP_ANA_CTRL\n", ret);
		goto disable_clk;
	}

	/*
	 * If VAG is powered-on (e.g. from previous boot), it would be disabled
	 * by the write to ANA_POWER in later steps of the probe code. This
	 * may create a loud pop even with all outputs muted. The proper way
	 * to circumvent this is disabling the bit first and waiting the proper
	 * cool-down time.
	 */
	ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, &value);
	if (ret) {
		dev_err(&client->dev, "Failed to read ANA_POWER: %d\n", ret);
		goto disable_clk;
	}
	if (value & SGTL5000_VAG_POWERUP) {
		ret = regmap_update_bits(sgtl5000->regmap,
					 SGTL5000_CHIP_ANA_POWER,
					 SGTL5000_VAG_POWERUP,
					 0);
		if (ret) {
			dev_err(&client->dev, "Error %d disabling VAG\n", ret);
			goto disable_clk;
		}

		msleep(SGTL5000_VAG_POWERDOWN_DELAY);
	}

	/* Follow section 2.2.1.1 of AN3663 */
	ana_pwr = SGTL5000_ANA_POWER_DEFAULT;
	if (sgtl5000->num_supplies <= VDDD) {
		/* internal VDDD at 1.2V */
		ret = regmap_update_bits(sgtl5000->regmap,
					 SGTL5000_CHIP_LINREG_CTRL,
					 SGTL5000_LINREG_VDDD_MASK,
					 LINREG_VDDD);
		if (ret)
			dev_err(&client->dev,
				"Error %d setting LINREG_VDDD\n", ret);

		ana_pwr |= SGTL5000_LINEREG_D_POWERUP;
		dev_info(&client->dev,
			 "Using internal LDO instead of VDDD: check ER1 erratum\n");
	} else {
		/* using external LDO for VDDD
		 * Clear startup powerup and simple powerup
		 * bits to save power
		 */
		ana_pwr &= ~(SGTL5000_STARTUP_POWERUP
			     | SGTL5000_LINREG_SIMPLE_POWERUP);
		dev_dbg(&client->dev, "Using external VDDD\n");
	}
	ret = regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, ana_pwr);
	if (ret)
		dev_err(&client->dev,
			"Error %d setting CHIP_ANA_POWER to %04x\n",
			ret, ana_pwr);

	if (np) {
		if (!of_property_read_u32(np,
			"micbias-resistor-k-ohms", &value)) {
			switch (value) {
			case SGTL5000_MICBIAS_OFF:
				sgtl5000->micbias_resistor = 0;
				break;
			case SGTL5000_MICBIAS_2K:
				sgtl5000->micbias_resistor = 1;
				break;
			case SGTL5000_MICBIAS_4K:
				sgtl5000->micbias_resistor = 2;
				break;
			case SGTL5000_MICBIAS_8K:
				sgtl5000->micbias_resistor = 3;
				break;
			default:
				sgtl5000->micbias_resistor = 2;
				dev_err(&client->dev,
					"Unsuitable MicBias resistor\n");
			}
		} else {
			/* default is 4Kohms */
			sgtl5000->micbias_resistor = 2;
		}
		if (!of_property_read_u32(np,
			"micbias-voltage-m-volts", &value)) {
			/* 1250mV => 0 */
			/* steps of 250mV */
			if ((value >= 1250) && (value <= 3000))
				sgtl5000->micbias_voltage = (value / 250) - 5;
			else {
				sgtl5000->micbias_voltage = 0;
				dev_err(&client->dev,
					"Unsuitable MicBias voltage\n");
			}
		} else {
			sgtl5000->micbias_voltage = 0;
		}
	}

	sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
	if (!of_property_read_u32(np, "lrclk-strength", &value)) {
		if (value > I2S_LRCLK_STRENGTH_HIGH)
			value = I2S_LRCLK_STRENGTH_LOW;
		sgtl5000->lrclk_strength = value;
	}

	sgtl5000->sclk_strength = I2S_SCLK_STRENGTH_LOW;
	if (!of_property_read_u32(np, "sclk-strength", &value)) {
		if (value > I2S_SCLK_STRENGTH_HIGH)
			value = I2S_SCLK_STRENGTH_LOW;
		sgtl5000->sclk_strength = value;
	}

	/* Ensure sgtl5000 will start with sane register values */
	sgtl5000_fill_defaults(client);

	ret = devm_snd_soc_register_component(&client->dev,
			&sgtl5000_driver, &sgtl5000_dai, 1);
	if (ret)
		goto disable_clk;

	return 0;

disable_clk:
	clk_disable_unprepare(sgtl5000->mclk);

disable_regs:
	regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
	regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);

	return ret;
}

static void sgtl5000_i2c_remove(struct i2c_client *client)
{
	struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);

	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT);
	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT);
	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT);

	clk_disable_unprepare(sgtl5000->mclk);
	regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
	regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);
}

static void sgtl5000_i2c_shutdown(struct i2c_client *client)
{
	sgtl5000_i2c_remove(client);
}

static const struct i2c_device_id sgtl5000_id[] = {
	{"sgtl5000"},
	{},
};

MODULE_DEVICE_TABLE(i2c, sgtl5000_id);

static const struct of_device_id sgtl5000_dt_ids[] = {
	{ .compatible = "fsl,sgtl5000", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);

static struct i2c_driver sgtl5000_i2c_driver = {
	.driver = {
		.name = "sgtl5000",
		.of_match_table = sgtl5000_dt_ids,
	},
	.probe = sgtl5000_i2c_probe,
	.remove = sgtl5000_i2c_remove,
	.shutdown = sgtl5000_i2c_shutdown,
	.id_table = sgtl5000_id,
};

module_i2c_driver(sgtl5000_i2c_driver);