Skip to content

Commit

Permalink
ASoC: tas2764: Extend driver to SN012776
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
  • Loading branch information
povik committed Mar 11, 2022
1 parent 3f0a1c8 commit cb66939
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
49 changes: 45 additions & 4 deletions sound/soc/codecs/tas2764.c
Expand Up @@ -16,6 +16,7 @@
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include <sound/pcm.h>
Expand All @@ -25,12 +26,19 @@

#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;
struct gpio_desc *sdz_gpio;
struct regmap *regmap;
struct device *dev;

enum tas2764_devid devid;

int v_sense_slot;
int i_sense_slot;
Expand Down Expand Up @@ -502,10 +510,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;

Expand All @@ -532,6 +546,23 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
if (ret < 0)
return ret;

if (tas2764->devid == 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;
}
}

return 0;
}

Expand Down Expand Up @@ -631,17 +662,28 @@ static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764)
return 0;
}

static const struct of_device_id tas2764_of_match[];

static int tas2764_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tas2764_priv *tas2764;
const struct of_device_id *of_id = NULL;
int result;

tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv),
GFP_KERNEL);
if (!tas2764)
return -ENOMEM;

if (client->dev.of_node)
of_id = of_match_device(tas2764_of_match, &client->dev);

if (of_id)
tas2764->devid = (enum tas2764_devid) of_id->data;
else
tas2764->devid = DEVID_TAS2764;

tas2764->dev = &client->dev;
i2c_set_clientdata(client, tas2764);
dev_set_drvdata(&client->dev, tas2764);
Expand Down Expand Up @@ -675,13 +717,12 @@ static const struct i2c_device_id tas2764_i2c_id[] = {
};
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);
#endif

static struct i2c_driver tas2764_i2c_driver = {
.driver = {
Expand Down
3 changes: 3 additions & 0 deletions sound/soc/codecs/tas2764.h
Expand Up @@ -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
Expand Down Expand Up @@ -87,4 +88,6 @@
#define TAS2764_TDM_CFG6_ISNS_ENABLE BIT(6)
#define TAS2764_TDM_CFG6_50_MASK GENMASK(5, 0)

#define TAS2764_BOP_CFG0 TAS2764_REG(0X0, 0x1d)

#endif /* __TAS2764__ */

0 comments on commit cb66939

Please sign in to comment.