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

Commit 1e9ca685 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/ab8500', 'asoc/topic/ac97' and...

Merge remote-tracking branches 'asoc/topic/ab8500', 'asoc/topic/ac97' and 'asoc/topic/cs35l32' into asoc-next
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
CS35L32 audio CODEC

Required properties:

  - compatible : "cirrus,cs35l32"

  - reg : the I2C address of the device for I2C. Address is determined by the level
  of the AD0 pin. Level 0 is 0x40 while Level 1 is 0x41.

  - VA-supply, VP-supply : power supplies for the device,
  as covered in Documentation/devicetree/bindings/regulator/regulator.txt.

Optional properties:

  - reset-gpios : a GPIO spec for the reset pin. If specified, it will be
  deasserted before communication to the codec starts.

  - cirrus,boost-manager : Boost voltage control.
  0 = Automatically managed.  Boost-converter output voltage is the higher
  of the two: Class G or adaptive LED voltage.
  1 = Automatically managed irrespective of audio, adapting for low-power
  dissipation when LEDs are ON, and operating in Fixed-Boost Bypass Mode
  if LEDs are OFF (VBST = VP).
  2 = (Default) Boost voltage fixed in Bypass Mode (VBST = VP).
  3 = Boost voltage fixed at 5 V.

  - cirrus,sdout-datacfg : Data configuration for dual CS35L32 applications only.
  Determines the data packed in a two-CS35L32 configuration.
  0 = Left/right channels VMON[11:0], IMON[11:0], VPMON[7:0].
  1 = Left/right channels VMON[11:0], IMON[11:0], STATUS.
  2 = (Default) left/right channels VMON[15:0], IMON [15:0].
  3 = Left/right channels VPMON[7:0], STATUS.

  - cirrus,sdout-share : SDOUT sharing. Determines whether one or two CS35L32
  devices are on board sharing SDOUT.
  0 = (Default) One IC.
  1 = Two IC's.

  - cirrus,battery-recovery : Low battery nominal recovery threshold, rising VP.
  0 = 3.1V
  1 = 3.2V
  2 = 3.3V (Default)
  3 = 3.4V

  - cirrus,battery-threshold : Low battery nominal threshold, falling VP.
  0 = 3.1V
  1 = 3.2V
  2 = 3.3V
  3 = 3.4V (Default)
  4 = 3.5V
  5 = 3.6V

Example:

codec: codec@40 {
	compatible = "cirrus,cs35l32";
	reg = <0x40>;
	reset-gpios = <&gpio 10 0>;
	cirrus,boost-manager = <0x03>;
	cirrus,sdout-datacfg = <0x02>;
	VA-supply = <&reg_audio>;
};
+26 −0
Original line number Diff line number Diff line
#ifndef __DT_CS35L32_H
#define __DT_CS35L32_H

#define CS35L32_BOOST_MGR_AUTO		0
#define CS35L32_BOOST_MGR_AUTO_AUDIO	1
#define CS35L32_BOOST_MGR_BYPASS	2
#define CS35L32_BOOST_MGR_FIXED		3

#define CS35L32_DATA_CFG_LR_VP		0
#define CS35L32_DATA_CFG_LR_STAT	1
#define CS35L32_DATA_CFG_LR		2
#define CS35L32_DATA_CFG_LR_VPSTAT	3

#define CS35L32_BATT_THRESH_3_1V	0
#define CS35L32_BATT_THRESH_3_2V	1
#define CS35L32_BATT_THRESH_3_3V	2
#define CS35L32_BATT_THRESH_3_4V	3

#define CS35L32_BATT_RECOV_3_1V		0
#define CS35L32_BATT_RECOV_3_2V		1
#define CS35L32_BATT_RECOV_3_3V		2
#define CS35L32_BATT_RECOV_3_4V		3
#define CS35L32_BATT_RECOV_3_5V		4
#define CS35L32_BATT_RECOV_3_6V		5

#endif /* __DT_CS35L32_H */
+5 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ config SND_SOC_ALL_CODECS
	select SND_SOC_ALC5623 if I2C
	select SND_SOC_ALC5632 if I2C
	select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
	select SND_SOC_CS35L32 if I2C
	select SND_SOC_CS42L51_I2C if I2C
	select SND_SOC_CS42L52 if I2C && INPUT
	select SND_SOC_CS42L56 if I2C && INPUT
@@ -325,6 +326,10 @@ config SND_SOC_ALC5632
config SND_SOC_CQ0093VC
	tristate

config SND_SOC_CS35L32
	tristate "Cirrus Logic CS35L32 CODEC"
	depends on I2C

config SND_SOC_CS42L51
	tristate

+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ snd-soc-ak4671-objs := ak4671.o
snd-soc-ak5386-objs := ak5386.o
snd-soc-arizona-objs := arizona.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs35l32-objs := cs35l32.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
snd-soc-cs42l52-objs := cs42l52.o
@@ -206,6 +207,7 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632)	+= snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_ARIZONA)	+= snd-soc-arizona.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CS35L32)	+= snd-soc-cs35l32.o
obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS42L51_I2C)	+= snd-soc-cs42l51-i2c.o
obj-$(CONFIG_SND_SOC_CS42L52)	+= snd-soc-cs42l52.o
+33 −40
Original line number Diff line number Diff line
@@ -56,8 +56,7 @@
#define GPIO31_DIR_OUTPUT			0x40

/* Macrocell register definitions */
#define AB8500_CTRL3_REG			0x0200
#define AB8500_GPIO_DIR4_REG			0x1013
#define AB8500_GPIO_DIR4_REG			0x13 /* Bank AB8500_MISC */

/* Nr of FIR/IIR-coeff banks in ANC-block */
#define AB8500_NR_OF_ANC_COEFF_BANKS		2
@@ -126,6 +125,8 @@ struct ab8500_codec_drvdata_dbg {

/* Private data for AB8500 device-driver */
struct ab8500_codec_drvdata {
	struct regmap *regmap;

	/* Sidetone */
	long *sid_fir_values;
	enum sid_state sid_status;
@@ -166,49 +167,35 @@ static inline const char *amic_type_str(enum amic_type type)
 */

/* Read a register from the audio-bank of AB8500 */
static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec,
					unsigned int reg)
static int ab8500_codec_read_reg(void *context, unsigned int reg,
				 unsigned int *value)
{
	struct device *dev = context;
	int status;
	unsigned int value = 0;

	u8 value8;
	status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO,
	status = abx500_get_register_interruptible(dev, AB8500_AUDIO,
						   reg, &value8);
	if (status < 0) {
		dev_err(codec->dev,
			"%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n",
			__func__, (u8)AB8500_AUDIO, (u8)reg, status);
	} else {
		dev_dbg(codec->dev,
			"%s: Read 0x%02x from register 0x%02x:0x%02x\n",
			__func__, value8, (u8)AB8500_AUDIO, (u8)reg);
		value = (unsigned int)value8;
	}
	*value = (unsigned int)value8;

	return value;
	return status;
}

/* Write to a register in the audio-bank of AB8500 */
static int ab8500_codec_write_reg(struct snd_soc_codec *codec,
				unsigned int reg, unsigned int value)
static int ab8500_codec_write_reg(void *context, unsigned int reg,
				  unsigned int value)
{
	int status;
	struct device *dev = context;

	status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO,
	return abx500_set_register_interruptible(dev, AB8500_AUDIO,
						 reg, value);
	if (status < 0)
		dev_err(codec->dev,
			"%s: ERROR: Register (%02x:%02x) write failed (%d).\n",
			__func__, (u8)AB8500_AUDIO, (u8)reg, status);
	else
		dev_dbg(codec->dev,
			"%s: Wrote 0x%02x into register %02x:%02x\n",
			__func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg);

	return status;
}

static const struct regmap_config ab8500_codec_regmap = {
	.reg_read = ab8500_codec_read_reg,
	.reg_write = ab8500_codec_write_reg,
};

/*
 * Controls - DAPM
 */
@@ -1968,16 +1955,16 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
	dev_dbg(codec->dev, "%s: Enter.\n", __func__);

	/* Set DMic-clocks to outputs */
	status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC,
						(u8)AB8500_GPIO_DIR4_REG,
	status = abx500_get_register_interruptible(codec->dev, AB8500_MISC,
						AB8500_GPIO_DIR4_REG,
						&value8);
	if (status < 0)
		return status;
	value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
		GPIO31_DIR_OUTPUT;
	status = abx500_set_register_interruptible(codec->dev,
						(u8)AB8500_MISC,
						(u8)AB8500_GPIO_DIR4_REG,
						AB8500_MISC,
						AB8500_GPIO_DIR4_REG,
						value);
	if (status < 0)
		return status;
@@ -2565,9 +2552,6 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)

static struct snd_soc_codec_driver ab8500_codec_driver = {
	.probe =		ab8500_codec_probe,
	.read =			ab8500_codec_read_reg,
	.write =		ab8500_codec_write_reg,
	.reg_word_size =	sizeof(u8),
	.controls =		ab8500_ctrls,
	.num_controls =		ARRAY_SIZE(ab8500_ctrls),
	.dapm_widgets =		ab8500_dapm_widgets,
@@ -2592,6 +2576,15 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
	drvdata->anc_status = ANC_UNCONFIGURED;
	dev_set_drvdata(&pdev->dev, drvdata);

	drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
					   &ab8500_codec_regmap);
	if (IS_ERR(drvdata->regmap)) {
		status = PTR_ERR(drvdata->regmap);
		dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
			__func__, status);
		return status;
	}

	dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
	status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
				ab8500_codec_dai,
Loading