Skip to content

Commit 6f0b47b

Browse files
committed
ASoc: tas2783A: Use acpi init data if present
The ACPI table has initialization data for each device which needs to be updated to device to configure the device correctly. This commit adds the change to read the entry "mipi-sdca-function-initialization-table" and update the device with the data. Signed-off-by: Niranjan H Y <niranjan.hy@ti.com> --- v2: - update commit message description
1 parent b0c39f2 commit 6f0b47b

2 files changed

Lines changed: 93 additions & 3 deletions

File tree

sound/soc/codecs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,6 +2103,7 @@ config SND_SOC_TAS2783_SDW
21032103
tristate "Texas Instruments TAS2783 speaker amplifier (sdw)"
21042104
depends on SOUNDWIRE
21052105
depends on EFI
2106+
depends on SND_SOC_SDCA
21062107
select REGMAP_SOUNDWIRE
21072108
select REGMAP_SOUNDWIRE_MBQ
21082109
select CRC32

sound/soc/codecs/tas2783-sdw.c

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <linux/soundwire/sdw.h>
2828
#include <linux/soundwire/sdw_registers.h>
2929
#include <linux/soundwire/sdw_type.h>
30+
#include <sound/sdca_function.h>
3031
#include <sound/sdw.h>
3132
#include <sound/soc.h>
3233
#include <sound/tlv.h>
@@ -40,6 +41,7 @@
4041
#define TAS2783_PROBE_TIMEOUT 5000
4142
#define TAS2783_CALI_GUID EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, \
4243
0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92)
44+
#define MIPI_INIT_TABLE "mipi-sdca-function-initialization-table"
4345

4446
static const u32 tas2783_cali_reg[] = {
4547
TAS2783_CAL_R0,
@@ -56,6 +58,11 @@ struct bin_header_t {
5658
u32 length;
5759
};
5860

61+
struct raw_init_data {
62+
__le32 addr;
63+
u8 val;
64+
} __packed;
65+
5966
struct calibration_data {
6067
u32 is_valid;
6168
unsigned long read_sz;
@@ -83,6 +90,8 @@ struct tas2783_prv {
8390
wait_queue_head_t fw_wait;
8491
bool fw_dl_task_done;
8592
bool fw_dl_success;
93+
struct reg_sequence *init_data;
94+
int num_init_data;
8695
};
8796

8897
static const struct reg_default tas2783_reg_default[] = {
@@ -1214,9 +1223,19 @@ static s32 tas_io_init(struct device *dev, struct sdw_slave *slave)
12141223
dev_err(tas_dev->dev, "fw request, wait_event timeout\n");
12151224
ret = -EAGAIN;
12161225
} else {
1217-
ret = regmap_multi_reg_write(tas_dev->regmap, tas2783_init_seq,
1218-
ARRAY_SIZE(tas2783_init_seq));
1219-
tas_dev->hw_init = true;
1226+
if (tas_dev->num_init_data > 0)
1227+
ret = regmap_multi_reg_write(tas_dev->regmap,
1228+
tas_dev->init_data,
1229+
tas_dev->num_init_data);
1230+
else
1231+
ret = regmap_multi_reg_write(tas_dev->regmap, tas2783_init_seq,
1232+
ARRAY_SIZE(tas2783_init_seq));
1233+
1234+
if (ret)
1235+
dev_err(tas_dev->dev,
1236+
"init writes failed, err=%d", ret);
1237+
else
1238+
tas_dev->hw_init = true;
12201239
}
12211240

12221241
return ret;
@@ -1260,6 +1279,73 @@ static void tas_remove(struct tas2783_prv *tas_dev)
12601279
snd_soc_unregister_component(tas_dev->dev);
12611280
}
12621281

1282+
static s32 tas_get_smartamp_init_data(struct sdw_slave *peripheral,
1283+
struct tas2783_prv *tas_dev)
1284+
{
1285+
int num_init_data, i;
1286+
struct device *dev;
1287+
struct reg_sequence *init_data;
1288+
struct sdca_device_data *sdca_data;
1289+
struct sdca_function_desc *function;
1290+
struct raw_init_data *raw __free(kfree) = NULL;
1291+
1292+
dev = &peripheral->dev;
1293+
sdca_data = &peripheral->sdca_data;
1294+
1295+
dev_dbg(dev, "number of functions found %d",
1296+
sdca_data->num_functions);
1297+
1298+
if (sdca_data->num_functions <= 0)
1299+
return -EINVAL;
1300+
1301+
/* look for smartamp function */
1302+
for (i = 0; i < sdca_data->num_functions; i++) {
1303+
if (sdca_data->function[i].type ==
1304+
SDCA_FUNCTION_TYPE_SMART_AMP)
1305+
break;
1306+
}
1307+
if (i == sdca_data->num_functions)
1308+
return -EINVAL;
1309+
1310+
function = &sdca_data->function[i];
1311+
num_init_data = fwnode_property_count_u8(function->node,
1312+
MIPI_INIT_TABLE);
1313+
if (num_init_data <= 0) {
1314+
dev_dbg(dev, "error reading init table for tas2783 err=%d",
1315+
num_init_data);
1316+
return num_init_data;
1317+
}
1318+
1319+
if (num_init_data % sizeof(*raw) != 0) {
1320+
dev_dbg(dev, "%s should be integer multiple of %lu",
1321+
MIPI_INIT_TABLE, sizeof(*raw));
1322+
return -EINVAL;
1323+
}
1324+
1325+
raw = kzalloc(num_init_data, GFP_KERNEL);
1326+
if (!raw)
1327+
return -ENOMEM;
1328+
1329+
fwnode_property_read_u8_array(function->node, MIPI_INIT_TABLE,
1330+
(u8 *)raw, num_init_data);
1331+
1332+
num_init_data /= sizeof(*raw);
1333+
init_data = devm_kcalloc(dev, num_init_data, sizeof(*init_data),
1334+
GFP_KERNEL);
1335+
if (!init_data)
1336+
return -ENOMEM;
1337+
1338+
for (i = 0; i < num_init_data; i++) {
1339+
init_data[i].reg = le32_to_cpu(raw[i].addr);
1340+
init_data[i].def = raw[i].val;
1341+
}
1342+
1343+
tas_dev->num_init_data = num_init_data;
1344+
tas_dev->init_data = init_data;
1345+
1346+
return 0;
1347+
}
1348+
12631349
static s32 tas_sdw_probe(struct sdw_slave *peripheral,
12641350
const struct sdw_device_id *id)
12651351
{
@@ -1272,6 +1358,8 @@ static s32 tas_sdw_probe(struct sdw_slave *peripheral,
12721358
return dev_err_probe(dev, -ENOMEM,
12731359
"Failed devm_kzalloc");
12741360

1361+
tas_get_smartamp_init_data(peripheral, tas_dev);
1362+
12751363
tas_dev->dev = dev;
12761364
tas_dev->sdw_peripheral = peripheral;
12771365
tas_dev->hw_init = false;
@@ -1325,6 +1413,7 @@ static struct sdw_driver tas_sdw_driver = {
13251413
};
13261414
module_sdw_driver(tas_sdw_driver);
13271415

1416+
MODULE_IMPORT_NS("SND_SOC_SDCA");
13281417
MODULE_AUTHOR("Texas Instruments Inc.");
13291418
MODULE_DESCRIPTION("ASoC TAS2783 SoundWire Driver");
13301419
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)