diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2008-01-10 08:37:42 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:50 -0500 |
commit | a7a4ac86b4754f44eb06221f3087debb4775d588 (patch) | |
tree | 63240035ca77fca21c4bb3b0db7566f53501053a /sound/soc | |
parent | 0b4d221b8d56deefca4984d01b3a010107ae1f72 (diff) |
[ALSA] ASoC TLV support
Add TLV support to ASoC.
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/soc-core.c | 66 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 14 |
2 files changed, 46 insertions, 34 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bd656db347ee..e748b00466b7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1213,7 +1213,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, | |||
1213 | memcpy(&template, _template, sizeof(template)); | 1213 | memcpy(&template, _template, sizeof(template)); |
1214 | if (long_name) | 1214 | if (long_name) |
1215 | template.name = long_name; | 1215 | template.name = long_name; |
1216 | template.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | ||
1217 | template.index = 0; | 1216 | template.index = 0; |
1218 | 1217 | ||
1219 | return snd_ctl_new1(&template, data); | 1218 | return snd_ctl_new1(&template, data); |
@@ -1348,13 +1347,16 @@ EXPORT_SYMBOL_GPL(snd_soc_info_enum_ext); | |||
1348 | int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, | 1347 | int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, |
1349 | struct snd_ctl_elem_info *uinfo) | 1348 | struct snd_ctl_elem_info *uinfo) |
1350 | { | 1349 | { |
1351 | int mask = kcontrol->private_value; | 1350 | int max = kcontrol->private_value; |
1351 | |||
1352 | if (max == 1) | ||
1353 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1354 | else | ||
1355 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1352 | 1356 | ||
1353 | uinfo->type = | ||
1354 | mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1355 | uinfo->count = 1; | 1357 | uinfo->count = 1; |
1356 | uinfo->value.integer.min = 0; | 1358 | uinfo->value.integer.min = 0; |
1357 | uinfo->value.integer.max = mask; | 1359 | uinfo->value.integer.max = max; |
1358 | return 0; | 1360 | return 0; |
1359 | } | 1361 | } |
1360 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); | 1362 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); |
@@ -1371,15 +1373,18 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); | |||
1371 | int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | 1373 | int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, |
1372 | struct snd_ctl_elem_info *uinfo) | 1374 | struct snd_ctl_elem_info *uinfo) |
1373 | { | 1375 | { |
1374 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1376 | int max = (kcontrol->private_value >> 16) & 0xff; |
1375 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1377 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1376 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1378 | int rshift = (kcontrol->private_value >> 12) & 0x0f; |
1377 | 1379 | ||
1378 | uinfo->type = | 1380 | if (max == 1) |
1379 | mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | 1381 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1382 | else | ||
1383 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1384 | |||
1380 | uinfo->count = shift == rshift ? 1 : 2; | 1385 | uinfo->count = shift == rshift ? 1 : 2; |
1381 | uinfo->value.integer.min = 0; | 1386 | uinfo->value.integer.min = 0; |
1382 | uinfo->value.integer.max = mask; | 1387 | uinfo->value.integer.max = max; |
1383 | return 0; | 1388 | return 0; |
1384 | } | 1389 | } |
1385 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | 1390 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); |
@@ -1400,7 +1405,8 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
1400 | int reg = kcontrol->private_value & 0xff; | 1405 | int reg = kcontrol->private_value & 0xff; |
1401 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1406 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1402 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1407 | int rshift = (kcontrol->private_value >> 12) & 0x0f; |
1403 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1408 | int max = (kcontrol->private_value >> 16) & 0xff; |
1409 | int mask = (1 << fls(max)) - 1; | ||
1404 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1410 | int invert = (kcontrol->private_value >> 24) & 0x01; |
1405 | 1411 | ||
1406 | ucontrol->value.integer.value[0] = | 1412 | ucontrol->value.integer.value[0] = |
@@ -1410,10 +1416,10 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
1410 | (snd_soc_read(codec, reg) >> rshift) & mask; | 1416 | (snd_soc_read(codec, reg) >> rshift) & mask; |
1411 | if (invert) { | 1417 | if (invert) { |
1412 | ucontrol->value.integer.value[0] = | 1418 | ucontrol->value.integer.value[0] = |
1413 | mask - ucontrol->value.integer.value[0]; | 1419 | max - ucontrol->value.integer.value[0]; |
1414 | if (shift != rshift) | 1420 | if (shift != rshift) |
1415 | ucontrol->value.integer.value[1] = | 1421 | ucontrol->value.integer.value[1] = |
1416 | mask - ucontrol->value.integer.value[1]; | 1422 | max - ucontrol->value.integer.value[1]; |
1417 | } | 1423 | } |
1418 | 1424 | ||
1419 | return 0; | 1425 | return 0; |
@@ -1436,25 +1442,24 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | |||
1436 | int reg = kcontrol->private_value & 0xff; | 1442 | int reg = kcontrol->private_value & 0xff; |
1437 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1443 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1438 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1444 | int rshift = (kcontrol->private_value >> 12) & 0x0f; |
1439 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1445 | int max = (kcontrol->private_value >> 16) & 0xff; |
1446 | int mask = (1 << fls(max)) - 1; | ||
1440 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1447 | int invert = (kcontrol->private_value >> 24) & 0x01; |
1441 | int err; | ||
1442 | unsigned short val, val2, val_mask; | 1448 | unsigned short val, val2, val_mask; |
1443 | 1449 | ||
1444 | val = (ucontrol->value.integer.value[0] & mask); | 1450 | val = (ucontrol->value.integer.value[0] & mask); |
1445 | if (invert) | 1451 | if (invert) |
1446 | val = mask - val; | 1452 | val = max - val; |
1447 | val_mask = mask << shift; | 1453 | val_mask = mask << shift; |
1448 | val = val << shift; | 1454 | val = val << shift; |
1449 | if (shift != rshift) { | 1455 | if (shift != rshift) { |
1450 | val2 = (ucontrol->value.integer.value[1] & mask); | 1456 | val2 = (ucontrol->value.integer.value[1] & mask); |
1451 | if (invert) | 1457 | if (invert) |
1452 | val2 = mask - val2; | 1458 | val2 = max - val2; |
1453 | val_mask |= mask << rshift; | 1459 | val_mask |= mask << rshift; |
1454 | val |= val2 << rshift; | 1460 | val |= val2 << rshift; |
1455 | } | 1461 | } |
1456 | err = snd_soc_update_bits(codec, reg, val_mask, val); | 1462 | return snd_soc_update_bits(codec, reg, val_mask, val); |
1457 | return err; | ||
1458 | } | 1463 | } |
1459 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | 1464 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); |
1460 | 1465 | ||
@@ -1471,13 +1476,16 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | |||
1471 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, | 1476 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, |
1472 | struct snd_ctl_elem_info *uinfo) | 1477 | struct snd_ctl_elem_info *uinfo) |
1473 | { | 1478 | { |
1474 | int mask = (kcontrol->private_value >> 12) & 0xff; | 1479 | int max = (kcontrol->private_value >> 12) & 0xff; |
1480 | |||
1481 | if (max == 1) | ||
1482 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1483 | else | ||
1484 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1475 | 1485 | ||
1476 | uinfo->type = | ||
1477 | mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1478 | uinfo->count = 2; | 1486 | uinfo->count = 2; |
1479 | uinfo->value.integer.min = 0; | 1487 | uinfo->value.integer.min = 0; |
1480 | uinfo->value.integer.max = mask; | 1488 | uinfo->value.integer.max = max; |
1481 | return 0; | 1489 | return 0; |
1482 | } | 1490 | } |
1483 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); | 1491 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); |
@@ -1498,7 +1506,8 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, | |||
1498 | int reg = kcontrol->private_value & 0xff; | 1506 | int reg = kcontrol->private_value & 0xff; |
1499 | int reg2 = (kcontrol->private_value >> 24) & 0xff; | 1507 | int reg2 = (kcontrol->private_value >> 24) & 0xff; |
1500 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1508 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1501 | int mask = (kcontrol->private_value >> 12) & 0xff; | 1509 | int max = (kcontrol->private_value >> 12) & 0xff; |
1510 | int mask = (1<<fls(max))-1; | ||
1502 | int invert = (kcontrol->private_value >> 20) & 0x01; | 1511 | int invert = (kcontrol->private_value >> 20) & 0x01; |
1503 | 1512 | ||
1504 | ucontrol->value.integer.value[0] = | 1513 | ucontrol->value.integer.value[0] = |
@@ -1507,9 +1516,9 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, | |||
1507 | (snd_soc_read(codec, reg2) >> shift) & mask; | 1516 | (snd_soc_read(codec, reg2) >> shift) & mask; |
1508 | if (invert) { | 1517 | if (invert) { |
1509 | ucontrol->value.integer.value[0] = | 1518 | ucontrol->value.integer.value[0] = |
1510 | mask - ucontrol->value.integer.value[0]; | 1519 | max - ucontrol->value.integer.value[0]; |
1511 | ucontrol->value.integer.value[1] = | 1520 | ucontrol->value.integer.value[1] = |
1512 | mask - ucontrol->value.integer.value[1]; | 1521 | max - ucontrol->value.integer.value[1]; |
1513 | } | 1522 | } |
1514 | 1523 | ||
1515 | return 0; | 1524 | return 0; |
@@ -1532,7 +1541,8 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, | |||
1532 | int reg = kcontrol->private_value & 0xff; | 1541 | int reg = kcontrol->private_value & 0xff; |
1533 | int reg2 = (kcontrol->private_value >> 24) & 0xff; | 1542 | int reg2 = (kcontrol->private_value >> 24) & 0xff; |
1534 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1543 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1535 | int mask = (kcontrol->private_value >> 12) & 0xff; | 1544 | int max = (kcontrol->private_value >> 12) & 0xff; |
1545 | int mask = (1 << fls(max)) - 1; | ||
1536 | int invert = (kcontrol->private_value >> 20) & 0x01; | 1546 | int invert = (kcontrol->private_value >> 20) & 0x01; |
1537 | int err; | 1547 | int err; |
1538 | unsigned short val, val2, val_mask; | 1548 | unsigned short val, val2, val_mask; |
@@ -1542,8 +1552,8 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, | |||
1542 | val2 = (ucontrol->value.integer.value[1] & mask); | 1552 | val2 = (ucontrol->value.integer.value[1] & mask); |
1543 | 1553 | ||
1544 | if (invert) { | 1554 | if (invert) { |
1545 | val = mask - val; | 1555 | val = max - val; |
1546 | val2 = mask - val2; | 1556 | val2 = max - val2; |
1547 | } | 1557 | } |
1548 | 1558 | ||
1549 | val = val << shift; | 1559 | val = val << shift; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 16ebb60ed3d4..7eb6c5c03775 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1018,8 +1018,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
1018 | int reg = kcontrol->private_value & 0xff; | 1018 | int reg = kcontrol->private_value & 0xff; |
1019 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1019 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1020 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1020 | int rshift = (kcontrol->private_value >> 12) & 0x0f; |
1021 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1021 | int max = (kcontrol->private_value >> 16) & 0xff; |
1022 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1022 | int invert = (kcontrol->private_value >> 24) & 0x01; |
1023 | int mask = (1 << fls(max)) - 1; | ||
1023 | 1024 | ||
1024 | /* return the saved value if we are powered down */ | 1025 | /* return the saved value if we are powered down */ |
1025 | if (widget->id == snd_soc_dapm_pga && !widget->power) { | 1026 | if (widget->id == snd_soc_dapm_pga && !widget->power) { |
@@ -1034,10 +1035,10 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
1034 | (snd_soc_read(widget->codec, reg) >> rshift) & mask; | 1035 | (snd_soc_read(widget->codec, reg) >> rshift) & mask; |
1035 | if (invert) { | 1036 | if (invert) { |
1036 | ucontrol->value.integer.value[0] = | 1037 | ucontrol->value.integer.value[0] = |
1037 | mask - ucontrol->value.integer.value[0]; | 1038 | max - ucontrol->value.integer.value[0]; |
1038 | if (shift != rshift) | 1039 | if (shift != rshift) |
1039 | ucontrol->value.integer.value[1] = | 1040 | ucontrol->value.integer.value[1] = |
1040 | mask - ucontrol->value.integer.value[1]; | 1041 | max - ucontrol->value.integer.value[1]; |
1041 | } | 1042 | } |
1042 | 1043 | ||
1043 | return 0; | 1044 | return 0; |
@@ -1060,7 +1061,8 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
1060 | int reg = kcontrol->private_value & 0xff; | 1061 | int reg = kcontrol->private_value & 0xff; |
1061 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1062 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
1062 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1063 | int rshift = (kcontrol->private_value >> 12) & 0x0f; |
1063 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1064 | int max = (kcontrol->private_value >> 16) & 0xff; |
1065 | int mask = (1 << fls(max)) - 1; | ||
1064 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1066 | int invert = (kcontrol->private_value >> 24) & 0x01; |
1065 | unsigned short val, val2, val_mask; | 1067 | unsigned short val, val2, val_mask; |
1066 | int ret; | 1068 | int ret; |
@@ -1068,13 +1070,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
1068 | val = (ucontrol->value.integer.value[0] & mask); | 1070 | val = (ucontrol->value.integer.value[0] & mask); |
1069 | 1071 | ||
1070 | if (invert) | 1072 | if (invert) |
1071 | val = mask - val; | 1073 | val = max - val; |
1072 | val_mask = mask << shift; | 1074 | val_mask = mask << shift; |
1073 | val = val << shift; | 1075 | val = val << shift; |
1074 | if (shift != rshift) { | 1076 | if (shift != rshift) { |
1075 | val2 = (ucontrol->value.integer.value[1] & mask); | 1077 | val2 = (ucontrol->value.integer.value[1] & mask); |
1076 | if (invert) | 1078 | if (invert) |
1077 | val2 = mask - val2; | 1079 | val2 = max - val2; |
1078 | val_mask |= mask << rshift; | 1080 | val_mask |= mask << rshift; |
1079 | val |= val2 << rshift; | 1081 | val |= val2 << rshift; |
1080 | } | 1082 | } |