diff options
Diffstat (limited to 'include/sound/soc.h')
-rw-r--r-- | include/sound/soc.h | 74 |
1 files changed, 44 insertions, 30 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 1890d87c5204..a1e0357a84d7 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,64 +45,68 @@ | |||
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, xmax, 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 | .max = xmax, .texts = xtexts } |
88 | #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ | 94 | #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \ |
89 | SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) | 95 | SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts) |
90 | #define SOC_ENUM_SINGLE_EXT(xmask, xtexts) \ | 96 | #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \ |
91 | { .mask = xmask, .texts = xtexts } | 97 | { .max = xmax, .texts = xtexts } |
92 | #define SOC_ENUM(xname, xenum) \ | 98 | #define SOC_ENUM(xname, xenum) \ |
93 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ | 99 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ |
94 | .info = snd_soc_info_enum_double, \ | 100 | .info = snd_soc_info_enum_double, \ |
95 | .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ | 101 | .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ |
96 | .private_value = (unsigned long)&xenum } | 102 | .private_value = (unsigned long)&xenum } |
97 | #define SOC_SINGLE_EXT(xname, xreg, xshift, xmask, xinvert,\ | 103 | #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\ |
98 | xhandler_get, xhandler_put) \ | 104 | xhandler_get, xhandler_put) \ |
99 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 105 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
100 | .info = snd_soc_info_volsw, \ | 106 | .info = snd_soc_info_volsw, \ |
101 | .get = xhandler_get, .put = xhandler_put, \ | 107 | .get = xhandler_get, .put = xhandler_put, \ |
102 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) } | 108 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } |
103 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmask, xinvert,\ | 109 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ |
104 | xhandler_get, xhandler_put, tlv_array) \ | 110 | xhandler_get, xhandler_put, tlv_array) \ |
105 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 111 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
106 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 112 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
@@ -108,7 +114,7 @@ | |||
108 | .tlv.p = (tlv_array), \ | 114 | .tlv.p = (tlv_array), \ |
109 | .info = snd_soc_info_volsw, \ | 115 | .info = snd_soc_info_volsw, \ |
110 | .get = xhandler_get, .put = xhandler_put, \ | 116 | .get = xhandler_get, .put = xhandler_put, \ |
111 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) } | 117 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } |
112 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ | 118 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ |
113 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 119 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
114 | .info = snd_soc_info_bool_ext, \ | 120 | .info = snd_soc_info_bool_ext, \ |
@@ -410,6 +416,8 @@ struct snd_soc_codec { | |||
410 | void *control_data; /* codec control (i2c/3wire) data */ | 416 | void *control_data; /* codec control (i2c/3wire) data */ |
411 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | 417 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); |
412 | int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); | 418 | int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); |
419 | int (*display_register)(struct snd_soc_codec *, char *, | ||
420 | size_t, unsigned int); | ||
413 | hw_write_t hw_write; | 421 | hw_write_t hw_write; |
414 | hw_read_t hw_read; | 422 | hw_read_t hw_read; |
415 | void *reg_cache; | 423 | void *reg_cache; |
@@ -516,13 +524,19 @@ struct snd_soc_pcm_runtime { | |||
516 | struct snd_soc_device *socdev; | 524 | struct snd_soc_device *socdev; |
517 | }; | 525 | }; |
518 | 526 | ||
527 | /* mixer control */ | ||
528 | struct soc_mixer_control { | ||
529 | int min, max; | ||
530 | unsigned int reg, rreg, shift, rshift, invert; | ||
531 | }; | ||
532 | |||
519 | /* enumerated kcontrol */ | 533 | /* enumerated kcontrol */ |
520 | struct soc_enum { | 534 | struct soc_enum { |
521 | unsigned short reg; | 535 | unsigned short reg; |
522 | unsigned short reg2; | 536 | unsigned short reg2; |
523 | unsigned char shift_l; | 537 | unsigned char shift_l; |
524 | unsigned char shift_r; | 538 | unsigned char shift_r; |
525 | unsigned int mask; | 539 | unsigned int max; |
526 | const char **texts; | 540 | const char **texts; |
527 | void *dapm; | 541 | void *dapm; |
528 | }; | 542 | }; |