Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add SDCA DAI ops helpers

Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>:

First, a couple of minor code fixups to already submitted code. Then
some patches to add new DAI ops helpers for the SDCA stuff, these allow
configuring things like the sample rate and finding out which SoundWire
port should be used for a specific SDCA streaming input/output terminal.
Still a few bits of outstanding work here (propogation of Cluster
information particularly) but his should be good enough to get some
basic use-cases working.

Hopefully we are getting fairly close to completing a first version of
the SDCA work now. Should be one more series to add FDL (firmware
downloading), then we should be able to send a first version of the
actual SDCA class driver itself.

Mark Brown da863e77 03aa2ed9

+490 -62
+19
include/sound/sdca_asoc.h
··· 11 11 #define __SDCA_ASOC_H__ 12 12 13 13 struct device; 14 + struct regmap; 14 15 struct sdca_function_data; 15 16 struct snd_kcontrol_new; 17 + struct snd_pcm_hw_params; 18 + struct snd_pcm_substream; 16 19 struct snd_soc_component_driver; 20 + struct snd_soc_dai; 17 21 struct snd_soc_dai_driver; 18 22 struct snd_soc_dai_ops; 19 23 struct snd_soc_dapm_route; ··· 42 38 struct snd_soc_component_driver *component_drv, 43 39 struct snd_soc_dai_driver **dai_drv, int *num_dai_drv, 44 40 const struct snd_soc_dai_ops *ops); 41 + 42 + int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap, 43 + struct sdca_function_data *function, 44 + struct snd_pcm_substream *substream, 45 + struct snd_soc_dai *dai); 46 + void sdca_asoc_free_constraints(struct snd_pcm_substream *substream, 47 + struct snd_soc_dai *dai); 48 + int sdca_asoc_get_port(struct device *dev, struct regmap *regmap, 49 + struct sdca_function_data *function, 50 + struct snd_soc_dai *dai); 51 + int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap, 52 + struct sdca_function_data *function, 53 + struct snd_pcm_substream *substream, 54 + struct snd_pcm_hw_params *params, 55 + struct snd_soc_dai *dai); 45 56 46 57 #endif // __SDCA_ASOC_H__
+31
include/sound/sdca_function.h
··· 186 186 }; 187 187 188 188 /** 189 + * enum sdca_dataport_selector_range - Column definitions for DataPort_Selector 190 + */ 191 + enum sdca_dataport_selector_range { 192 + SDCA_DATAPORT_SELECTOR_NCOLS = 16, 193 + SDCA_DATAPORT_SELECTOR_NROWS = 4, 194 + }; 195 + 196 + /** 189 197 * enum sdca_mu_controls - SDCA Controls for Mixer Unit 190 198 * 191 199 * Control Selectors for Mixer Unit from SDCA specification v1.0 ··· 1277 1269 }; 1278 1270 1279 1271 /** 1272 + * enum sdca_cluster_range - SDCA Range column definitions for ClusterIndex 1273 + */ 1274 + enum sdca_cluster_range { 1275 + SDCA_CLUSTER_BYTEINDEX = 0, 1276 + SDCA_CLUSTER_CLUSTERID = 1, 1277 + SDCA_CLUSTER_NCOLS = 2, 1278 + }; 1279 + 1280 + /** 1280 1281 * struct sdca_function_data - top-level information for one SDCA function 1281 1282 * @desc: Pointer to short descriptor from initial parsing. 1282 1283 * @init_table: Pointer to a table of initialization writes. ··· 1332 1315 int sdca_parse_function(struct device *dev, 1333 1316 struct sdca_function_desc *desc, 1334 1317 struct sdca_function_data *function); 1318 + 1319 + struct sdca_control *sdca_selector_find_control(struct device *dev, 1320 + struct sdca_entity *entity, 1321 + const int sel); 1322 + struct sdca_control_range *sdca_control_find_range(struct device *dev, 1323 + struct sdca_entity *entity, 1324 + struct sdca_control *control, 1325 + int cols, int rows); 1326 + struct sdca_control_range *sdca_selector_find_range(struct device *dev, 1327 + struct sdca_entity *entity, 1328 + int sel, int cols, int rows); 1329 + struct sdca_cluster *sdca_id_find_cluster(struct device *dev, 1330 + struct sdca_function_data *function, 1331 + const int id); 1335 1332 1336 1333 #endif
+3
include/sound/soc-dai.h
··· 463 463 464 464 /* bit field */ 465 465 unsigned int probed:1; 466 + 467 + /* DAI private data */ 468 + void *priv; 466 469 }; 467 470 468 471 static inline const struct snd_soc_pcm_stream *
+367 -60
sound/soc/sdca/sdca_asoc.c
··· 7 7 * https://www.mipi.org/mipi-sdca-v1-0-download 8 8 */ 9 9 10 + #include <linux/bits.h> 10 11 #include <linux/bitmap.h> 12 + #include <linux/build_bug.h> 11 13 #include <linux/delay.h> 12 14 #include <linux/dev_printk.h> 13 15 #include <linux/device.h> 14 16 #include <linux/minmax.h> 15 17 #include <linux/module.h> 16 18 #include <linux/overflow.h> 19 + #include <linux/regmap.h> 17 20 #include <linux/soundwire/sdw_registers.h> 18 21 #include <linux/string_helpers.h> 22 + #include <linux/types.h> 19 23 #include <sound/control.h> 24 + #include <sound/pcm.h> 25 + #include <sound/pcm_params.h> 20 26 #include <sound/sdca.h> 21 27 #include <sound/sdca_asoc.h> 22 28 #include <sound/sdca_function.h> ··· 31 25 #include <sound/soc-dai.h> 32 26 #include <sound/soc-dapm.h> 33 27 #include <sound/tlv.h> 34 - 35 - static struct sdca_control *selector_find_control(struct device *dev, 36 - struct sdca_entity *entity, 37 - const int sel) 38 - { 39 - int i; 40 - 41 - for (i = 0; i < entity->num_controls; i++) { 42 - struct sdca_control *control = &entity->controls[i]; 43 - 44 - if (control->sel == sel) 45 - return control; 46 - } 47 - 48 - dev_err(dev, "%s: control %#x: missing\n", entity->label, sel); 49 - return NULL; 50 - } 51 - 52 - static struct sdca_control_range *control_find_range(struct device *dev, 53 - struct sdca_entity *entity, 54 - struct sdca_control *control, 55 - int cols, int rows) 56 - { 57 - struct sdca_control_range *range = &control->range; 58 - 59 - if ((cols && range->cols != cols) || (rows && range->rows != rows) || 60 - !range->data) { 61 - dev_err(dev, "%s: control %#x: ranges invalid (%d,%d)\n", 62 - entity->label, control->sel, range->cols, range->rows); 63 - return NULL; 64 - } 65 - 66 - return range; 67 - } 68 - 69 - static struct sdca_control_range *selector_find_range(struct device *dev, 70 - struct sdca_entity *entity, 71 - int sel, int cols, int rows) 72 - { 73 - struct sdca_control *control; 74 - 75 - control = selector_find_control(dev, entity, sel); 76 - if (!control) 77 - return NULL; 78 - 79 - return control_find_range(dev, entity, control, cols, rows); 80 - } 81 28 82 29 static bool exported_control(struct sdca_entity *entity, struct sdca_control *control) 83 30 { ··· 172 213 const char **texts; 173 214 int i; 174 215 175 - control = selector_find_control(dev, entity, SDCA_CTL_GE_SELECTED_MODE); 216 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_GE_SELECTED_MODE); 176 217 if (!control) 177 218 return -EINVAL; 178 219 ··· 180 221 dev_warn(dev, "%s: unexpected access layer: %x\n", 181 222 entity->label, control->layers); 182 223 183 - range = control_find_range(dev, entity, control, SDCA_SELECTED_MODE_NCOLS, 0); 224 + range = sdca_control_find_range(dev, entity, control, SDCA_SELECTED_MODE_NCOLS, 0); 184 225 if (!range) 185 226 return -EINVAL; 186 227 ··· 402 443 unsigned int mask = 0; 403 444 int i; 404 445 405 - control = selector_find_control(dev, entity, SDCA_CTL_PDE_REQUESTED_PS); 446 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_PDE_REQUESTED_PS); 406 447 if (!control) 407 448 return -EINVAL; 408 449 ··· 411 452 dev_warn(dev, "%s: unexpected access layer: %x\n", 412 453 entity->label, control->layers); 413 454 414 - range = control_find_range(dev, entity, control, SDCA_REQUESTED_PS_NCOLS, 0); 455 + range = sdca_control_find_range(dev, entity, control, SDCA_REQUESTED_PS_NCOLS, 0); 415 456 if (!range) 416 457 return -EINVAL; 417 458 ··· 458 499 return -EINVAL; 459 500 } 460 501 461 - range = selector_find_range(dev, entity->group, SDCA_CTL_GE_SELECTED_MODE, 462 - SDCA_SELECTED_MODE_NCOLS, 0); 502 + range = sdca_selector_find_range(dev, entity->group, SDCA_CTL_GE_SELECTED_MODE, 503 + SDCA_SELECTED_MODE_NCOLS, 0); 463 504 if (!range) 464 505 return -EINVAL; 465 506 ··· 572 613 return -EINVAL; 573 614 } 574 615 575 - control = selector_find_control(dev, entity, SDCA_CTL_SU_SELECTOR); 616 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_SU_SELECTOR); 576 617 if (!control) 577 618 return -EINVAL; 578 619 ··· 602 643 return -EINVAL; 603 644 } 604 645 605 - control = selector_find_control(dev, entity, SDCA_CTL_MU_MIXER); 646 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_MU_MIXER); 606 647 if (!control) 607 648 return -EINVAL; 608 649 ··· 812 853 /* 813 854 * FIXME: For now only handle the simple case of a single linear range 814 855 */ 815 - range = control_find_range(dev, entity, control, SDCA_VOLUME_LINEAR_NCOLS, 1); 856 + range = sdca_control_find_range(dev, entity, control, SDCA_VOLUME_LINEAR_NCOLS, 1); 816 857 if (!range) 817 858 return -EINVAL; 818 859 ··· 1099 1140 } 1100 1141 1101 1142 if (entity->iot.clock) { 1102 - range = selector_find_range(dev, entity->iot.clock, 1103 - SDCA_CTL_CS_SAMPLERATEINDEX, 1104 - SDCA_SAMPLERATEINDEX_NCOLS, 0); 1143 + range = sdca_selector_find_range(dev, entity->iot.clock, 1144 + SDCA_CTL_CS_SAMPLERATEINDEX, 1145 + SDCA_SAMPLERATEINDEX_NCOLS, 0); 1105 1146 if (!range) 1106 1147 return -EINVAL; 1107 1148 ··· 1113 1154 clock_rates = UINT_MAX; 1114 1155 } 1115 1156 1116 - range = selector_find_range(dev, entity, sel, SDCA_USAGE_NCOLS, 0); 1157 + range = sdca_selector_find_range(dev, entity, sel, SDCA_USAGE_NCOLS, 0); 1117 1158 if (!range) 1118 1159 return -EINVAL; 1119 1160 ··· 1275 1316 return 0; 1276 1317 } 1277 1318 EXPORT_SYMBOL_NS(sdca_asoc_populate_component, "SND_SOC_SDCA"); 1319 + 1320 + /** 1321 + * sdca_asoc_set_constraints - constrain channels available on a DAI 1322 + * @dev: Pointer to the device, used for error messages. 1323 + * @regmap: Pointer to the Function register map. 1324 + * @function: Pointer to the Function information. 1325 + * @substream: Pointer to the PCM substream. 1326 + * @dai: Pointer to the ASoC DAI. 1327 + * 1328 + * Typically called from startup(). 1329 + * 1330 + * Return: Returns zero on success, and a negative error code on failure. 1331 + */ 1332 + int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap, 1333 + struct sdca_function_data *function, 1334 + struct snd_pcm_substream *substream, 1335 + struct snd_soc_dai *dai) 1336 + { 1337 + static const unsigned int channel_list[] = { 1338 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1339 + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 1340 + }; 1341 + struct sdca_entity *entity = &function->entities[dai->id]; 1342 + struct snd_pcm_hw_constraint_list *constraint; 1343 + struct sdca_control_range *range; 1344 + struct sdca_control *control; 1345 + unsigned int channel_mask = 0; 1346 + int i, ret; 1347 + 1348 + static_assert(ARRAY_SIZE(channel_list) == SDCA_MAX_CHANNEL_COUNT); 1349 + static_assert(sizeof(channel_mask) * BITS_PER_BYTE >= SDCA_MAX_CHANNEL_COUNT); 1350 + 1351 + if (entity->type != SDCA_ENTITY_TYPE_IT) 1352 + return 0; 1353 + 1354 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_IT_CLUSTERINDEX); 1355 + if (!control) 1356 + return -EINVAL; 1357 + 1358 + range = sdca_control_find_range(dev, entity, control, SDCA_CLUSTER_NCOLS, 0); 1359 + if (!range) 1360 + return -EINVAL; 1361 + 1362 + for (i = 0; i < range->rows; i++) { 1363 + int clusterid = sdca_range(range, SDCA_CLUSTER_CLUSTERID, i); 1364 + struct sdca_cluster *cluster; 1365 + 1366 + cluster = sdca_id_find_cluster(dev, function, clusterid); 1367 + if (!cluster) 1368 + return -ENODEV; 1369 + 1370 + channel_mask |= (1 << (cluster->num_channels - 1)); 1371 + } 1372 + 1373 + dev_dbg(dev, "%s: set channel constraint mask: %#x\n", 1374 + entity->label, channel_mask); 1375 + 1376 + constraint = kzalloc(sizeof(*constraint), GFP_KERNEL); 1377 + if (!constraint) 1378 + return -ENOMEM; 1379 + 1380 + constraint->count = ARRAY_SIZE(channel_list); 1381 + constraint->list = channel_list; 1382 + constraint->mask = channel_mask; 1383 + 1384 + ret = snd_pcm_hw_constraint_list(substream->runtime, 0, 1385 + SNDRV_PCM_HW_PARAM_CHANNELS, 1386 + constraint); 1387 + if (ret) { 1388 + dev_err(dev, "%s: failed to add constraint: %d\n", entity->label, ret); 1389 + kfree(constraint); 1390 + return ret; 1391 + } 1392 + 1393 + dai->priv = constraint; 1394 + 1395 + return 0; 1396 + } 1397 + EXPORT_SYMBOL_NS(sdca_asoc_set_constraints, "SND_SOC_SDCA"); 1398 + 1399 + /** 1400 + * sdca_asoc_free_constraints - free constraint allocations 1401 + * @substream: Pointer to the PCM substream. 1402 + * @dai: Pointer to the ASoC DAI. 1403 + * 1404 + * Typically called from shutdown(). 1405 + */ 1406 + void sdca_asoc_free_constraints(struct snd_pcm_substream *substream, 1407 + struct snd_soc_dai *dai) 1408 + { 1409 + struct snd_pcm_hw_constraint_list *constraint = dai->priv; 1410 + 1411 + kfree(constraint); 1412 + } 1413 + EXPORT_SYMBOL_NS(sdca_asoc_free_constraints, "SND_SOC_SDCA"); 1414 + 1415 + /** 1416 + * sdca_asoc_get_port - return SoundWire port for a DAI 1417 + * @dev: Pointer to the device, used for error messages. 1418 + * @regmap: Pointer to the Function register map. 1419 + * @function: Pointer to the Function information. 1420 + * @dai: Pointer to the ASoC DAI. 1421 + * 1422 + * Typically called from hw_params(). 1423 + * 1424 + * Return: Returns a positive port number on success, and a negative error 1425 + * code on failure. 1426 + */ 1427 + int sdca_asoc_get_port(struct device *dev, struct regmap *regmap, 1428 + struct sdca_function_data *function, 1429 + struct snd_soc_dai *dai) 1430 + { 1431 + struct sdca_entity *entity = &function->entities[dai->id]; 1432 + struct sdca_control_range *range; 1433 + unsigned int reg, val; 1434 + int sel = -EINVAL; 1435 + int i, ret; 1436 + 1437 + switch (entity->type) { 1438 + case SDCA_ENTITY_TYPE_IT: 1439 + sel = SDCA_CTL_IT_DATAPORT_SELECTOR; 1440 + break; 1441 + case SDCA_ENTITY_TYPE_OT: 1442 + sel = SDCA_CTL_OT_DATAPORT_SELECTOR; 1443 + break; 1444 + default: 1445 + break; 1446 + } 1447 + 1448 + if (sel < 0 || !entity->iot.is_dataport) { 1449 + dev_err(dev, "%s: port number only available for dataports\n", 1450 + entity->label); 1451 + return -EINVAL; 1452 + } 1453 + 1454 + range = sdca_selector_find_range(dev, entity, sel, SDCA_DATAPORT_SELECTOR_NCOLS, 1455 + SDCA_DATAPORT_SELECTOR_NROWS); 1456 + if (!range) 1457 + return -EINVAL; 1458 + 1459 + reg = SDW_SDCA_CTL(function->desc->adr, entity->id, sel, 0); 1460 + 1461 + ret = regmap_read(regmap, reg, &val); 1462 + if (ret) { 1463 + dev_err(dev, "%s: failed to read dataport selector: %d\n", 1464 + entity->label, ret); 1465 + return ret; 1466 + } 1467 + 1468 + for (i = 0; i < range->rows; i++) { 1469 + static const u8 port_mask = 0xF; 1470 + 1471 + sel = sdca_range(range, val & port_mask, i); 1472 + 1473 + /* 1474 + * FIXME: Currently only a single dataport is supported, so 1475 + * return the first one found, technically up to 4 dataports 1476 + * could be linked, but this is not yet supported. 1477 + */ 1478 + if (sel != 0xFF) 1479 + return sel; 1480 + 1481 + val >>= hweight8(port_mask); 1482 + } 1483 + 1484 + dev_err(dev, "%s: no dataport found\n", entity->label); 1485 + return -ENODEV; 1486 + } 1487 + EXPORT_SYMBOL_NS(sdca_asoc_get_port, "SND_SOC_SDCA"); 1488 + 1489 + static int set_cluster(struct device *dev, struct regmap *regmap, 1490 + struct sdca_function_data *function, 1491 + struct sdca_entity *entity, unsigned int channels) 1492 + { 1493 + int sel = SDCA_CTL_IT_CLUSTERINDEX; 1494 + struct sdca_control_range *range; 1495 + int i, ret; 1496 + 1497 + range = sdca_selector_find_range(dev, entity, sel, SDCA_CLUSTER_NCOLS, 0); 1498 + if (!range) 1499 + return -EINVAL; 1500 + 1501 + for (i = 0; i < range->rows; i++) { 1502 + int cluster_id = sdca_range(range, SDCA_CLUSTER_CLUSTERID, i); 1503 + struct sdca_cluster *cluster; 1504 + 1505 + cluster = sdca_id_find_cluster(dev, function, cluster_id); 1506 + if (!cluster) 1507 + return -ENODEV; 1508 + 1509 + if (cluster->num_channels == channels) { 1510 + int index = sdca_range(range, SDCA_CLUSTER_BYTEINDEX, i); 1511 + unsigned int reg = SDW_SDCA_CTL(function->desc->adr, 1512 + entity->id, sel, 0); 1513 + 1514 + ret = regmap_update_bits(regmap, reg, 0xFF, index); 1515 + if (ret) { 1516 + dev_err(dev, "%s: failed to write cluster index: %d\n", 1517 + entity->label, ret); 1518 + return ret; 1519 + } 1520 + 1521 + dev_dbg(dev, "%s: set cluster to %d (%d channels)\n", 1522 + entity->label, index, channels); 1523 + 1524 + return 0; 1525 + } 1526 + } 1527 + 1528 + dev_err(dev, "%s: no cluster for %d channels\n", entity->label, channels); 1529 + return -EINVAL; 1530 + } 1531 + 1532 + static int set_clock(struct device *dev, struct regmap *regmap, 1533 + struct sdca_function_data *function, 1534 + struct sdca_entity *entity, int target_rate) 1535 + { 1536 + int sel = SDCA_CTL_CS_SAMPLERATEINDEX; 1537 + struct sdca_control_range *range; 1538 + int i, ret; 1539 + 1540 + range = sdca_selector_find_range(dev, entity, sel, SDCA_SAMPLERATEINDEX_NCOLS, 0); 1541 + if (!range) 1542 + return -EINVAL; 1543 + 1544 + for (i = 0; i < range->rows; i++) { 1545 + unsigned int rate = sdca_range(range, SDCA_SAMPLERATEINDEX_RATE, i); 1546 + 1547 + if (rate == target_rate) { 1548 + unsigned int index = sdca_range(range, 1549 + SDCA_SAMPLERATEINDEX_INDEX, 1550 + i); 1551 + unsigned int reg = SDW_SDCA_CTL(function->desc->adr, 1552 + entity->id, sel, 0); 1553 + 1554 + ret = regmap_update_bits(regmap, reg, 0xFF, index); 1555 + if (ret) { 1556 + dev_err(dev, "%s: failed to write clock rate: %d\n", 1557 + entity->label, ret); 1558 + return ret; 1559 + } 1560 + 1561 + dev_dbg(dev, "%s: set clock rate to %d (%dHz)\n", 1562 + entity->label, index, rate); 1563 + 1564 + return 0; 1565 + } 1566 + } 1567 + 1568 + dev_err(dev, "%s: no clock rate for %dHz\n", entity->label, target_rate); 1569 + return -EINVAL; 1570 + } 1571 + 1572 + static int set_usage(struct device *dev, struct regmap *regmap, 1573 + struct sdca_function_data *function, 1574 + struct sdca_entity *entity, int sel, 1575 + int target_rate, int target_width) 1576 + { 1577 + struct sdca_control_range *range; 1578 + int i, ret; 1579 + 1580 + range = sdca_selector_find_range(dev, entity, sel, SDCA_USAGE_NCOLS, 0); 1581 + if (!range) 1582 + return -EINVAL; 1583 + 1584 + for (i = 0; i < range->rows; i++) { 1585 + unsigned int rate = sdca_range(range, SDCA_USAGE_SAMPLE_RATE, i); 1586 + unsigned int width = sdca_range(range, SDCA_USAGE_SAMPLE_WIDTH, i); 1587 + 1588 + if ((!rate || rate == target_rate) && width == target_width) { 1589 + unsigned int usage = sdca_range(range, SDCA_USAGE_NUMBER, i); 1590 + unsigned int reg = SDW_SDCA_CTL(function->desc->adr, 1591 + entity->id, sel, 0); 1592 + 1593 + ret = regmap_update_bits(regmap, reg, 0xFF, usage); 1594 + if (ret) { 1595 + dev_err(dev, "%s: failed to write usage: %d\n", 1596 + entity->label, ret); 1597 + return ret; 1598 + } 1599 + 1600 + dev_dbg(dev, "%s: set usage to %#x (%dHz, %d bits)\n", 1601 + entity->label, usage, target_rate, target_width); 1602 + 1603 + return 0; 1604 + } 1605 + } 1606 + 1607 + dev_err(dev, "%s: no usage for %dHz, %dbits\n", 1608 + entity->label, target_rate, target_width); 1609 + return -EINVAL; 1610 + } 1611 + 1612 + /** 1613 + * sdca_asoc_hw_params - set SDCA channels, sample rate and bit depth 1614 + * @dev: Pointer to the device, used for error messages. 1615 + * @regmap: Pointer to the Function register map. 1616 + * @function: Pointer to the Function information. 1617 + * @substream: Pointer to the PCM substream. 1618 + * @params: Pointer to the hardware parameters. 1619 + * @dai: Pointer to the ASoC DAI. 1620 + * 1621 + * Typically called from hw_params(). 1622 + * 1623 + * Return: Returns zero on success, and a negative error code on failure. 1624 + */ 1625 + int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap, 1626 + struct sdca_function_data *function, 1627 + struct snd_pcm_substream *substream, 1628 + struct snd_pcm_hw_params *params, 1629 + struct snd_soc_dai *dai) 1630 + { 1631 + struct sdca_entity *entity = &function->entities[dai->id]; 1632 + int channels = params_channels(params); 1633 + int width = params_width(params); 1634 + int rate = params_rate(params); 1635 + int usage_sel; 1636 + int ret; 1637 + 1638 + switch (entity->type) { 1639 + case SDCA_ENTITY_TYPE_IT: 1640 + ret = set_cluster(dev, regmap, function, entity, channels); 1641 + if (ret) 1642 + return ret; 1643 + 1644 + usage_sel = SDCA_CTL_IT_USAGE; 1645 + break; 1646 + case SDCA_ENTITY_TYPE_OT: 1647 + usage_sel = SDCA_CTL_OT_USAGE; 1648 + break; 1649 + default: 1650 + dev_err(dev, "%s: hw_params on non-terminal entity\n", entity->label); 1651 + return -EINVAL; 1652 + } 1653 + 1654 + if (entity->iot.clock) { 1655 + ret = set_clock(dev, regmap, function, entity->iot.clock, rate); 1656 + if (ret) 1657 + return ret; 1658 + } 1659 + 1660 + ret = set_usage(dev, regmap, function, entity, usage_sel, rate, width); 1661 + if (ret) 1662 + return ret; 1663 + 1664 + return 0; 1665 + } 1666 + EXPORT_SYMBOL_NS(sdca_asoc_hw_params, "SND_SOC_SDCA");
+70 -2
sound/soc/sdca/sdca_functions.c
··· 881 881 control->value = tmp; 882 882 control->has_fixed = true; 883 883 } 884 - 884 + fallthrough; 885 + case SDCA_ACCESS_MODE_RO: 885 886 control->deferrable = fwnode_property_read_bool(control_node, 886 887 "mipi-sdca-control-deferrable"); 887 888 break; ··· 1635 1634 ret = fwnode_property_read_u64(entity_node, "mipi-sdca-input-pin-list", &pin_list); 1636 1635 if (ret == -EINVAL) { 1637 1636 /* Allow missing pin lists, assume no pins. */ 1638 - dev_warn(dev, "%s: missing pin list\n", entity->label); 1639 1637 return 0; 1640 1638 } else if (ret) { 1641 1639 dev_err(dev, "%s: failed to read pin list: %d\n", entity->label, ret); ··· 1940 1940 return 0; 1941 1941 } 1942 1942 EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA"); 1943 + 1944 + struct sdca_control *sdca_selector_find_control(struct device *dev, 1945 + struct sdca_entity *entity, 1946 + const int sel) 1947 + { 1948 + int i; 1949 + 1950 + for (i = 0; i < entity->num_controls; i++) { 1951 + struct sdca_control *control = &entity->controls[i]; 1952 + 1953 + if (control->sel == sel) 1954 + return control; 1955 + } 1956 + 1957 + dev_err(dev, "%s: control %#x: missing\n", entity->label, sel); 1958 + return NULL; 1959 + } 1960 + EXPORT_SYMBOL_NS(sdca_selector_find_control, "SND_SOC_SDCA"); 1961 + 1962 + struct sdca_control_range *sdca_control_find_range(struct device *dev, 1963 + struct sdca_entity *entity, 1964 + struct sdca_control *control, 1965 + int cols, int rows) 1966 + { 1967 + struct sdca_control_range *range = &control->range; 1968 + 1969 + if ((cols && range->cols != cols) || (rows && range->rows != rows) || 1970 + !range->data) { 1971 + dev_err(dev, "%s: control %#x: ranges invalid (%d,%d)\n", 1972 + entity->label, control->sel, range->cols, range->rows); 1973 + return NULL; 1974 + } 1975 + 1976 + return range; 1977 + } 1978 + EXPORT_SYMBOL_NS(sdca_control_find_range, "SND_SOC_SDCA"); 1979 + 1980 + struct sdca_control_range *sdca_selector_find_range(struct device *dev, 1981 + struct sdca_entity *entity, 1982 + int sel, int cols, int rows) 1983 + { 1984 + struct sdca_control *control; 1985 + 1986 + control = sdca_selector_find_control(dev, entity, sel); 1987 + if (!control) 1988 + return NULL; 1989 + 1990 + return sdca_control_find_range(dev, entity, control, cols, rows); 1991 + } 1992 + EXPORT_SYMBOL_NS(sdca_selector_find_range, "SND_SOC_SDCA"); 1993 + 1994 + struct sdca_cluster *sdca_id_find_cluster(struct device *dev, 1995 + struct sdca_function_data *function, 1996 + const int id) 1997 + { 1998 + int i; 1999 + 2000 + for (i = 0; i < function->num_clusters; i++) { 2001 + struct sdca_cluster *cluster = &function->clusters[i]; 2002 + 2003 + if (cluster->id == id) 2004 + return cluster; 2005 + } 2006 + 2007 + dev_err(dev, "%s: cluster %#x: missing\n", function->desc->name, id); 2008 + return NULL; 2009 + } 2010 + EXPORT_SYMBOL_NS(sdca_id_find_cluster, "SND_SOC_SDCA"); 1943 2011 1944 2012 MODULE_LICENSE("Dual BSD/GPL"); 1945 2013 MODULE_DESCRIPTION("SDCA library");