]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: tas2764: Extend driver to SN012776
authorMartin Povišer <povik+lin@cutebit.org>
Thu, 27 Feb 2025 12:07:30 +0000 (22:07 +1000)
committerMark Brown <broonie@kernel.org>
Thu, 13 Mar 2025 22:39:01 +0000 (22:39 +0000)
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: Neal Gompa <neal@gompa.dev>
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-3-cbb130030acf@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/tas2764.c
sound/soc/codecs/tas2764.h

index c0a1d0c2a93890105a169717a7fb75ec05f93146..d9b4f898789fa9b59c94c97e3b130950b88c3a76 100644 (file)
@@ -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>
 
 #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,7 +36,8 @@ 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);
index 9490f2686e38919a726e649884d9b6ad761493a2..69c0f91cb423986f7f0ded0b2160927f024d957d 100644 (file)
@@ -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
 #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__ */