Unverified Commit ad183929 authored by Martin Povišer's avatar Martin Povišer Committed by Mark Brown
Browse files

ASoC: tas2764: Extend driver to SN012776



SN012776 is a speaker amp chip found in Apple's 2021 laptops. It appears
similar and more-or-less compatible to TAS2764. Extend the TAS2764
driver with some SN012776 specifics and configure the chip assuming
it's in one of the Apple machines.

Reviewed-by: default avatarNeal Gompa <neal@gompa.dev>
Signed-off-by: default avatarMartin Povišer <povik+lin@cutebit.org>
Signed-off-by: default avatarJames Calligeros <jcalligeros99@gmail.com>
Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-3-cbb130030acf@gmail.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent ce923393
Loading
Loading
Loading
Loading
+40 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include <sound/pcm.h>
@@ -23,6 +24,11 @@

#include "tas2764.h"

enum tas2764_devid {
	DEVID_TAS2764  = 0,
	DEVID_SN012776 = 1
};

struct tas2764_priv {
	struct snd_soc_component *component;
	struct gpio_desc *reset_gpio;
@@ -30,6 +36,7 @@ struct tas2764_priv {
	struct regmap *regmap;
	struct device *dev;
	int irq;
	enum tas2764_devid devid;

	int v_sense_slot;
	int i_sense_slot;
@@ -533,10 +540,16 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = {
	},
};

static uint8_t sn012776_bop_presets[] = {
	0x01, 0x32, 0x02, 0x22, 0x83, 0x2d, 0x80, 0x02, 0x06,
	0x32, 0x46, 0x30, 0x02, 0x06, 0x38, 0x40, 0x30, 0x02,
	0x06, 0x3e, 0x37, 0x30, 0xff, 0xe6
};

static int tas2764_codec_probe(struct snd_soc_component *component)
{
	struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
	int ret;
	int ret, i;

	tas2764->component = component;

@@ -585,6 +598,27 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
	if (ret < 0)
		return ret;

	switch (tas2764->devid) {
	case DEVID_SN012776:
		ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
					TAS2764_PWR_CTRL_BOP_SRC,
					TAS2764_PWR_CTRL_BOP_SRC);
		if (ret < 0)
			return ret;

		for (i = 0; i < ARRAY_SIZE(sn012776_bop_presets); i++) {
			ret = snd_soc_component_write(component,
						TAS2764_BOP_CFG0 + i,
						sn012776_bop_presets[i]);

			if (ret < 0)
				return ret;
		}
		break;
	default:
		break;
	}

	return 0;
}

@@ -716,6 +750,8 @@ static int tas2764_i2c_probe(struct i2c_client *client)
	if (!tas2764)
		return -ENOMEM;

	tas2764->devid = (enum tas2764_devid)of_device_get_match_data(&client->dev);

	tas2764->dev = &client->dev;
	tas2764->irq = client->irq;
	i2c_set_clientdata(client, tas2764);
@@ -752,7 +788,8 @@ MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id);

#if defined(CONFIG_OF)
static const struct of_device_id tas2764_of_match[] = {
	{ .compatible = "ti,tas2764" },
	{ .compatible = "ti,tas2764",  .data = (void *)DEVID_TAS2764 },
	{ .compatible = "ti,sn012776", .data = (void *)DEVID_SN012776 },
	{},
};
MODULE_DEVICE_TABLE(of, tas2764_of_match);
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#define TAS2764_PWR_CTRL_ACTIVE		0x0
#define TAS2764_PWR_CTRL_MUTE		BIT(0)
#define TAS2764_PWR_CTRL_SHUTDOWN	BIT(1)
#define TAS2764_PWR_CTRL_BOP_SRC	BIT(7)

#define TAS2764_VSENSE_POWER_EN		3
#define TAS2764_ISENSE_POWER_EN		4
@@ -116,4 +117,6 @@
#define TAS2764_INT_CLK_CFG             TAS2764_REG(0x0, 0x5c)
#define TAS2764_INT_CLK_CFG_IRQZ_CLR    BIT(2)

#define TAS2764_BOP_CFG0                TAS2764_REG(0X0, 0x1d)

#endif /* __TAS2764__ */