diff options
-rw-r--r-- | include/sound/soc.h | 50 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 86 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 52 |
3 files changed, 114 insertions, 74 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 2ce530efcf11..e647a34c8091 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -26,10 +26,12 @@ | |||
26 | /* | 26 | /* |
27 | * Convenience kcontrol builders | 27 | * Convenience kcontrol builders |
28 | */ | 28 | */ |
29 | #define SOC_SINGLE_VALUE(reg, shift, max, invert) ((reg) | ((shift) << 8) |\ | 29 | #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ |
30 | ((shift) << 12) | ((max) << 16) | ((invert) << 24)) | 30 | ((unsigned long)&(struct soc_mixer_control) \ |
31 | #define SOC_SINGLE_VALUE_EXT(reg, max, invert) ((reg) | ((max) << 16) |\ | 31 | {.reg = xreg, .shift = xshift, .max = xmax, .invert = xinvert}) |
32 | ((invert) << 31)) | 32 | #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ |
33 | ((unsigned long)&(struct soc_mixer_control) \ | ||
34 | {.reg = xreg, .max = xmax, .invert = xinvert}) | ||
33 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ | 35 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ |
34 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 36 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
35 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 37 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
@@ -43,45 +45,49 @@ | |||
43 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 45 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
44 | .put = snd_soc_put_volsw, \ | 46 | .put = snd_soc_put_volsw, \ |
45 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | 47 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } |
46 | #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ | 48 | #define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \ |
47 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 49 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
48 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ | 50 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ |
49 | .put = snd_soc_put_volsw, \ | 51 | .put = snd_soc_put_volsw, \ |
50 | .private_value = (reg) | ((shift_left) << 8) | \ | 52 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
51 | ((shift_right) << 12) | ((max) << 16) | ((invert) << 24) } | 53 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ |
52 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, max, invert) \ | 54 | .max = xmax, .invert = xinvert} } |
55 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ | ||
53 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 56 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
54 | .info = snd_soc_info_volsw_2r, \ | 57 | .info = snd_soc_info_volsw_2r, \ |
55 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 58 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ |
56 | .private_value = (reg_left) | ((shift) << 8) | \ | 59 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
57 | ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) } | 60 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ |
58 | #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ | 61 | .max = xmax, .invert = xinvert} } |
62 | #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ | ||
59 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 63 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
60 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 64 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
61 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | 65 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ |
62 | .tlv.p = (tlv_array), \ | 66 | .tlv.p = (tlv_array), \ |
63 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ | 67 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ |
64 | .put = snd_soc_put_volsw, \ | 68 | .put = snd_soc_put_volsw, \ |
65 | .private_value = (reg) | ((shift_left) << 8) | \ | 69 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
66 | ((shift_right) << 12) | ((max) << 16) | ((invert) << 24) } | 70 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ |
67 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \ | 71 | .max = xmax, .invert = xinvert} } |
72 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ | ||
68 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 73 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
69 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 74 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
70 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | 75 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ |
71 | .tlv.p = (tlv_array), \ | 76 | .tlv.p = (tlv_array), \ |
72 | .info = snd_soc_info_volsw_2r, \ | 77 | .info = snd_soc_info_volsw_2r, \ |
73 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 78 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ |
74 | .private_value = (reg_left) | ((shift) << 8) | \ | 79 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
75 | ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) } | 80 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ |
76 | #define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \ | 81 | .max = xmax, .invert = xinvert} } |
82 | #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ | ||
77 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 83 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
78 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 84 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ |
79 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | 85 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ |
80 | .tlv.p = (tlv_array), \ | 86 | .tlv.p = (tlv_array), \ |
81 | .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ | 87 | .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ |
82 | .put = snd_soc_put_volsw_s8, \ | 88 | .put = snd_soc_put_volsw_s8, \ |
83 | .private_value = (reg) | (((signed char)max) << 16) | \ | 89 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
84 | (((signed char)min) << 24) } | 90 | {.reg = xreg, .min = xmin, .max = xmax} } |
85 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ | 91 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ |
86 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ | 92 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ |
87 | .mask = xmask, .texts = xtexts } | 93 | .mask = xmask, .texts = xtexts } |
@@ -518,6 +524,12 @@ struct snd_soc_pcm_runtime { | |||
518 | struct snd_soc_device *socdev; | 524 | struct snd_soc_device *socdev; |
519 | }; | 525 | }; |
520 | 526 | ||
527 | /* mixer control */ | ||
528 | struct soc_mixer_control { | ||
529 | int min, max; | ||
530 | uint reg, rreg, shift, rshift, invert; | ||
531 | }; | ||
532 | |||
521 | /* enumerated kcontrol */ | 533 | /* enumerated kcontrol */ |
522 | struct soc_enum { | 534 | struct soc_enum { |
523 | unsigned short reg; | 535 | unsigned short reg; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5d3bf731a4b2..4b94f1f6ee27 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1454,9 +1454,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); | |||
1454 | int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | 1454 | int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, |
1455 | struct snd_ctl_elem_info *uinfo) | 1455 | struct snd_ctl_elem_info *uinfo) |
1456 | { | 1456 | { |
1457 | int max = (kcontrol->private_value >> 16) & 0xff; | 1457 | struct soc_mixer_control *mc = |
1458 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1458 | (struct soc_mixer_control *)kcontrol->private_value; |
1459 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1459 | int max = mc->max; |
1460 | uint shift = mc->min; | ||
1461 | uint rshift = mc->rshift; | ||
1460 | 1462 | ||
1461 | if (max == 1) | 1463 | if (max == 1) |
1462 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1464 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
@@ -1482,13 +1484,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | |||
1482 | int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | 1484 | int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, |
1483 | struct snd_ctl_elem_value *ucontrol) | 1485 | struct snd_ctl_elem_value *ucontrol) |
1484 | { | 1486 | { |
1487 | struct soc_mixer_control *mc = | ||
1488 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1485 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1489 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1486 | int reg = kcontrol->private_value & 0xff; | 1490 | uint reg = mc->reg; |
1487 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1491 | uint shift = mc->shift; |
1488 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1492 | uint rshift = mc->rshift; |
1489 | int max = (kcontrol->private_value >> 16) & 0xff; | 1493 | int max = mc->max; |
1490 | int mask = (1 << fls(max)) - 1; | 1494 | uint mask = (1 << fls(max)) - 1; |
1491 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1495 | uint invert = mc->invert; |
1492 | 1496 | ||
1493 | ucontrol->value.integer.value[0] = | 1497 | ucontrol->value.integer.value[0] = |
1494 | (snd_soc_read(codec, reg) >> shift) & mask; | 1498 | (snd_soc_read(codec, reg) >> shift) & mask; |
@@ -1519,13 +1523,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); | |||
1519 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | 1523 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, |
1520 | struct snd_ctl_elem_value *ucontrol) | 1524 | struct snd_ctl_elem_value *ucontrol) |
1521 | { | 1525 | { |
1526 | struct soc_mixer_control *mc = | ||
1527 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1522 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1528 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1523 | int reg = kcontrol->private_value & 0xff; | 1529 | uint reg = mc->reg; |
1524 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1530 | uint shift = mc->shift; |
1525 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1531 | uint rshift = mc->rshift; |
1526 | int max = (kcontrol->private_value >> 16) & 0xff; | 1532 | int max = mc->max; |
1527 | int mask = (1 << fls(max)) - 1; | 1533 | uint mask = (1 << fls(max)) - 1; |
1528 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1534 | uint invert = mc->invert; |
1529 | unsigned short val, val2, val_mask; | 1535 | unsigned short val, val2, val_mask; |
1530 | 1536 | ||
1531 | val = (ucontrol->value.integer.value[0] & mask); | 1537 | val = (ucontrol->value.integer.value[0] & mask); |
@@ -1557,7 +1563,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | |||
1557 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, | 1563 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, |
1558 | struct snd_ctl_elem_info *uinfo) | 1564 | struct snd_ctl_elem_info *uinfo) |
1559 | { | 1565 | { |
1560 | int max = (kcontrol->private_value >> 12) & 0xff; | 1566 | struct soc_mixer_control *mc = |
1567 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1568 | int max = mc->max; | ||
1561 | 1569 | ||
1562 | if (max == 1) | 1570 | if (max == 1) |
1563 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1571 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
@@ -1583,13 +1591,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); | |||
1583 | int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, | 1591 | int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, |
1584 | struct snd_ctl_elem_value *ucontrol) | 1592 | struct snd_ctl_elem_value *ucontrol) |
1585 | { | 1593 | { |
1594 | struct soc_mixer_control *mc = | ||
1595 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1586 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1596 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1587 | int reg = kcontrol->private_value & 0xff; | 1597 | uint reg = mc->reg; |
1588 | int reg2 = (kcontrol->private_value >> 24) & 0xff; | 1598 | uint reg2 = mc->rreg; |
1589 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1599 | uint shift = mc->shift; |
1590 | int max = (kcontrol->private_value >> 12) & 0xff; | 1600 | int max = mc->max; |
1591 | int mask = (1<<fls(max))-1; | 1601 | uint mask = (1<<fls(max))-1; |
1592 | int invert = (kcontrol->private_value >> 20) & 0x01; | 1602 | uint invert = mc->invert; |
1593 | 1603 | ||
1594 | ucontrol->value.integer.value[0] = | 1604 | ucontrol->value.integer.value[0] = |
1595 | (snd_soc_read(codec, reg) >> shift) & mask; | 1605 | (snd_soc_read(codec, reg) >> shift) & mask; |
@@ -1618,13 +1628,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r); | |||
1618 | int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, | 1628 | int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, |
1619 | struct snd_ctl_elem_value *ucontrol) | 1629 | struct snd_ctl_elem_value *ucontrol) |
1620 | { | 1630 | { |
1631 | struct soc_mixer_control *mc = | ||
1632 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1621 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1633 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1622 | int reg = kcontrol->private_value & 0xff; | 1634 | uint reg = mc->reg; |
1623 | int reg2 = (kcontrol->private_value >> 24) & 0xff; | 1635 | uint reg2 = mc->rreg; |
1624 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1636 | uint shift = mc->shift; |
1625 | int max = (kcontrol->private_value >> 12) & 0xff; | 1637 | int max = mc->max; |
1626 | int mask = (1 << fls(max)) - 1; | 1638 | uint mask = (1 << fls(max)) - 1; |
1627 | int invert = (kcontrol->private_value >> 20) & 0x01; | 1639 | uint invert = mc->invert; |
1628 | int err; | 1640 | int err; |
1629 | unsigned short val, val2, val_mask; | 1641 | unsigned short val, val2, val_mask; |
1630 | 1642 | ||
@@ -1661,8 +1673,10 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); | |||
1661 | int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, | 1673 | int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, |
1662 | struct snd_ctl_elem_info *uinfo) | 1674 | struct snd_ctl_elem_info *uinfo) |
1663 | { | 1675 | { |
1664 | int max = (signed char)((kcontrol->private_value >> 16) & 0xff); | 1676 | struct soc_mixer_control *mc = |
1665 | int min = (signed char)((kcontrol->private_value >> 24) & 0xff); | 1677 | (struct soc_mixer_control *)kcontrol->private_value; |
1678 | int max = mc->max; | ||
1679 | int min = mc->min; | ||
1666 | 1680 | ||
1667 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 1681 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1668 | uinfo->count = 2; | 1682 | uinfo->count = 2; |
@@ -1684,9 +1698,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); | |||
1684 | int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, | 1698 | int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, |
1685 | struct snd_ctl_elem_value *ucontrol) | 1699 | struct snd_ctl_elem_value *ucontrol) |
1686 | { | 1700 | { |
1701 | struct soc_mixer_control *mc = | ||
1702 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1687 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1703 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1688 | int reg = kcontrol->private_value & 0xff; | 1704 | uint reg = mc->reg; |
1689 | int min = (signed char)((kcontrol->private_value >> 24) & 0xff); | 1705 | int min = mc->min; |
1690 | int val = snd_soc_read(codec, reg); | 1706 | int val = snd_soc_read(codec, reg); |
1691 | 1707 | ||
1692 | ucontrol->value.integer.value[0] = | 1708 | ucontrol->value.integer.value[0] = |
@@ -1709,9 +1725,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8); | |||
1709 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | 1725 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, |
1710 | struct snd_ctl_elem_value *ucontrol) | 1726 | struct snd_ctl_elem_value *ucontrol) |
1711 | { | 1727 | { |
1728 | struct soc_mixer_control *mc = | ||
1729 | (struct soc_mixer_control *)kcontrol->private_value; | ||
1712 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1730 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1713 | int reg = kcontrol->private_value & 0xff; | 1731 | uint reg = mc->reg; |
1714 | int min = (signed char)((kcontrol->private_value >> 24) & 0xff); | 1732 | int min = mc->min; |
1715 | unsigned short val; | 1733 | unsigned short val; |
1716 | 1734 | ||
1717 | val = (ucontrol->value.integer.value[0]+min) & 0xff; | 1735 | val = (ucontrol->value.integer.value[0]+min) & 0xff; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f9d100bc8479..bbdca0dacba6 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -104,10 +104,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
104 | case snd_soc_dapm_switch: | 104 | case snd_soc_dapm_switch: |
105 | case snd_soc_dapm_mixer: { | 105 | case snd_soc_dapm_mixer: { |
106 | int val; | 106 | int val; |
107 | int reg = w->kcontrols[i].private_value & 0xff; | 107 | struct soc_mixer_control *mc = (struct soc_mixer_control *) |
108 | int shift = (w->kcontrols[i].private_value >> 8) & 0x0f; | 108 | w->kcontrols[i].private_value; |
109 | int mask = (w->kcontrols[i].private_value >> 16) & 0xff; | 109 | uint reg = mc->reg; |
110 | int invert = (w->kcontrols[i].private_value >> 24) & 0x01; | 110 | uint shift = mc->shift; |
111 | int max = mc->max; | ||
112 | uint mask = (1 << fls(max)) - 1; | ||
113 | uint invert = mc->invert; | ||
111 | 114 | ||
112 | val = snd_soc_read(w->codec, reg); | 115 | val = snd_soc_read(w->codec, reg); |
113 | val = (val >> shift) & mask; | 116 | val = (val >> shift) & mask; |
@@ -247,16 +250,19 @@ static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power) | |||
247 | return 0; | 250 | return 0; |
248 | 251 | ||
249 | if (widget->num_kcontrols && k) { | 252 | if (widget->num_kcontrols && k) { |
250 | int reg = k->private_value & 0xff; | 253 | struct soc_mixer_control *mc = |
251 | int shift = (k->private_value >> 8) & 0x0f; | 254 | (struct soc_mixer_control *)k->private_value; |
252 | int mask = (k->private_value >> 16) & 0xff; | 255 | uint reg = mc->reg; |
253 | int invert = (k->private_value >> 24) & 0x01; | 256 | uint shift = mc->shift; |
257 | int max = mc->max; | ||
258 | uint mask = (1 << fls(max)) - 1; | ||
259 | uint invert = mc->invert; | ||
254 | 260 | ||
255 | if (power) { | 261 | if (power) { |
256 | int i; | 262 | int i; |
257 | /* power up has happended, increase volume to last level */ | 263 | /* power up has happended, increase volume to last level */ |
258 | if (invert) { | 264 | if (invert) { |
259 | for (i = mask; i > widget->saved_value; i--) | 265 | for (i = max; i > widget->saved_value; i--) |
260 | snd_soc_update_bits(widget->codec, reg, mask, i); | 266 | snd_soc_update_bits(widget->codec, reg, mask, i); |
261 | } else { | 267 | } else { |
262 | for (i = 0; i < widget->saved_value; i++) | 268 | for (i = 0; i < widget->saved_value; i++) |
@@ -1133,12 +1139,14 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
1133 | struct snd_ctl_elem_value *ucontrol) | 1139 | struct snd_ctl_elem_value *ucontrol) |
1134 | { | 1140 | { |
1135 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 1141 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); |
1136 | int reg = kcontrol->private_value & 0xff; | 1142 | struct soc_mixer_control *mc = |
1137 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1143 | (struct soc_mixer_control *)kcontrol->private_value; |
1138 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1144 | uint reg = mc->reg; |
1139 | int max = (kcontrol->private_value >> 16) & 0xff; | 1145 | uint shift = mc->shift; |
1140 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1146 | uint rshift = mc->rshift; |
1141 | int mask = (1 << fls(max)) - 1; | 1147 | int max = mc->max; |
1148 | uint invert = mc->invert; | ||
1149 | uint mask = (1 << fls(max)) - 1; | ||
1142 | 1150 | ||
1143 | /* return the saved value if we are powered down */ | 1151 | /* return the saved value if we are powered down */ |
1144 | if (widget->id == snd_soc_dapm_pga && !widget->power) { | 1152 | if (widget->id == snd_soc_dapm_pga && !widget->power) { |
@@ -1176,12 +1184,14 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
1176 | struct snd_ctl_elem_value *ucontrol) | 1184 | struct snd_ctl_elem_value *ucontrol) |
1177 | { | 1185 | { |
1178 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 1186 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); |
1179 | int reg = kcontrol->private_value & 0xff; | 1187 | struct soc_mixer_control *mc = |
1180 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 1188 | (struct soc_mixer_control *)kcontrol->private_value; |
1181 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | 1189 | uint reg = mc->reg; |
1182 | int max = (kcontrol->private_value >> 16) & 0xff; | 1190 | uint shift = mc->shift; |
1183 | int mask = (1 << fls(max)) - 1; | 1191 | uint rshift = mc->rshift; |
1184 | int invert = (kcontrol->private_value >> 24) & 0x01; | 1192 | int max = mc->max; |
1193 | uint mask = (1 << fls(max)) - 1; | ||
1194 | uint invert = mc->invert; | ||
1185 | unsigned short val, val2, val_mask; | 1195 | unsigned short val, val2, val_mask; |
1186 | int ret; | 1196 | int ret; |
1187 | 1197 | ||