Skip to content

Commit 79dba34

Browse files
committed
ASoc: tas2783A: Use acpi init data if present
Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
1 parent 8eb94ba commit 79dba34

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)