diff options
-rw-r--r-- | include/sound/ak4xxx-adda.h | 37 | ||||
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 203 |
2 files changed, 161 insertions, 79 deletions
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h index acf8cc1292e0..3d9888492026 100644 --- a/include/sound/ak4xxx-adda.h +++ b/include/sound/ak4xxx-adda.h | |||
@@ -32,8 +32,8 @@ struct snd_akm4xxx; | |||
32 | struct snd_ak4xxx_ops { | 32 | struct snd_ak4xxx_ops { |
33 | void (*lock)(struct snd_akm4xxx *ak, int chip); | 33 | void (*lock)(struct snd_akm4xxx *ak, int chip); |
34 | void (*unlock)(struct snd_akm4xxx *ak, int chip); | 34 | void (*unlock)(struct snd_akm4xxx *ak, int chip); |
35 | void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val); | 35 | void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
36 | // unsigned char (*read)(struct snd_akm4xxx *ak, int chip, unsigned char reg); | 36 | unsigned char val); |
37 | void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate); | 37 | void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate); |
38 | }; | 38 | }; |
39 | 39 | ||
@@ -41,31 +41,40 @@ struct snd_ak4xxx_ops { | |||
41 | 41 | ||
42 | struct snd_akm4xxx { | 42 | struct snd_akm4xxx { |
43 | struct snd_card *card; | 43 | struct snd_card *card; |
44 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ | 44 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ |
45 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ | 45 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ |
46 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ | 46 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ |
47 | unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image for IPGA (AK4528) */ | 47 | unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image |
48 | * for IPGA (AK4528) | ||
49 | */ | ||
48 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 50 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
49 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 51 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
50 | /* template should fill the following fields */ | 52 | /* template should fill the following fields */ |
51 | unsigned int idx_offset; /* control index offset */ | 53 | unsigned int idx_offset; /* control index offset */ |
52 | enum { | 54 | enum { |
53 | SND_AK4524, SND_AK4528, SND_AK4529, | 55 | SND_AK4524, SND_AK4528, SND_AK4529, |
54 | SND_AK4355, SND_AK4358, SND_AK4381 | 56 | SND_AK4355, SND_AK4358, SND_AK4381 |
55 | } type; | 57 | } type; |
56 | unsigned int *num_stereo; /* array of combined counts for the mixer */ | 58 | unsigned int *num_stereo; /* array of combined counts |
57 | char **channel_names; /* array of mixer channel names */ | 59 | * for the mixer |
60 | */ | ||
61 | char **channel_names; /* array of mixer channel names */ | ||
58 | struct snd_ak4xxx_ops ops; | 62 | struct snd_ak4xxx_ops ops; |
59 | }; | 63 | }; |
60 | 64 | ||
61 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val); | 65 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
66 | unsigned char val); | ||
62 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state); | 67 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state); |
63 | void snd_akm4xxx_init(struct snd_akm4xxx *ak); | 68 | void snd_akm4xxx_init(struct snd_akm4xxx *ak); |
64 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak); | 69 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak); |
65 | 70 | ||
66 | #define snd_akm4xxx_get(ak,chip,reg) (ak)->images[(chip) * 16 + (reg)] | 71 | #define snd_akm4xxx_get(ak,chip,reg) \ |
67 | #define snd_akm4xxx_set(ak,chip,reg,val) ((ak)->images[(chip) * 16 + (reg)] = (val)) | 72 | (ak)->images[(chip) * 16 + (reg)] |
68 | #define snd_akm4xxx_get_ipga(ak,chip,reg) (ak)->ipga_gain[chip][(reg)-4] | 73 | #define snd_akm4xxx_set(ak,chip,reg,val) \ |
69 | #define snd_akm4xxx_set_ipga(ak,chip,reg,val) ((ak)->ipga_gain[chip][(reg)-4] = (val)) | 74 | ((ak)->images[(chip) * 16 + (reg)] = (val)) |
75 | #define snd_akm4xxx_get_ipga(ak,chip,reg) \ | ||
76 | (ak)->ipga_gain[chip][(reg)-4] | ||
77 | #define snd_akm4xxx_set_ipga(ak,chip,reg,val) \ | ||
78 | ((ak)->ipga_gain[chip][(reg)-4] = (val)) | ||
70 | 79 | ||
71 | #endif /* __SOUND_AK4XXX_ADDA_H */ | 80 | #endif /* __SOUND_AK4XXX_ADDA_H */ |
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index f68bd740e1a1..dc7cc2001b74 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -34,7 +34,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>"); | |||
34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); | 34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val) | 37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
38 | unsigned char val) | ||
38 | { | 39 | { |
39 | ak->ops.lock(ak, chip); | 40 | ak->ops.lock(ak, chip); |
40 | ak->ops.write(ak, chip, reg, val); | 41 | ak->ops.write(ak, chip, reg, val); |
@@ -52,6 +53,67 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
52 | ak->ops.unlock(ak, chip); | 53 | ak->ops.unlock(ak, chip); |
53 | } | 54 | } |
54 | 55 | ||
56 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
57 | |||
58 | /* reset procedure for AK4524 and AK4528 */ | ||
59 | static void ak4524_reset(struct snd_akm4xxx *ak, int state) | ||
60 | { | ||
61 | unsigned int chip; | ||
62 | unsigned char reg, maxreg; | ||
63 | |||
64 | if (ak->type == SND_AK4528) | ||
65 | maxreg = 0x06; | ||
66 | else | ||
67 | maxreg = 0x08; | ||
68 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
69 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
70 | if (state) | ||
71 | continue; | ||
72 | /* DAC volumes */ | ||
73 | for (reg = 0x04; reg < maxreg; reg++) | ||
74 | snd_akm4xxx_write(ak, chip, reg, | ||
75 | snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, | ||
81 | snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /* reset procedure for AK4355 and AK4358 */ | ||
86 | static void ak4355_reset(struct snd_akm4xxx *ak, int state) | ||
87 | { | ||
88 | unsigned char reg; | ||
89 | |||
90 | if (state) { | ||
91 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
92 | return; | ||
93 | } | ||
94 | for (reg = 0x00; reg < 0x0b; reg++) | ||
95 | if (reg != 0x01) | ||
96 | snd_akm4xxx_write(ak, 0, reg, | ||
97 | snd_akm4xxx_get(ak, 0, reg)); | ||
98 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
99 | } | ||
100 | |||
101 | /* reset procedure for AK4381 */ | ||
102 | static void ak4381_reset(struct snd_akm4xxx *ak, int state) | ||
103 | { | ||
104 | unsigned int chip; | ||
105 | unsigned char reg; | ||
106 | |||
107 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
108 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
109 | if (state) | ||
110 | continue; | ||
111 | for (reg = 0x01; reg < 0x05; reg++) | ||
112 | snd_akm4xxx_write(ak, chip, reg, | ||
113 | snd_akm4xxx_get(ak, chip, reg)); | ||
114 | } | ||
115 | } | ||
116 | |||
55 | /* | 117 | /* |
56 | * reset the AKM codecs | 118 | * reset the AKM codecs |
57 | * @state: 1 = reset codec, 0 = restore the registers | 119 | * @state: 1 = reset codec, 0 = restore the registers |
@@ -60,52 +122,26 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
60 | */ | 122 | */ |
61 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) | 123 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) |
62 | { | 124 | { |
63 | unsigned int chip; | ||
64 | unsigned char reg; | ||
65 | |||
66 | switch (ak->type) { | 125 | switch (ak->type) { |
67 | case SND_AK4524: | 126 | case SND_AK4524: |
68 | case SND_AK4528: | 127 | case SND_AK4528: |
69 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 128 | ak4524_reset(ak, state); |
70 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
71 | if (state) | ||
72 | continue; | ||
73 | /* DAC volumes */ | ||
74 | for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++) | ||
75 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
81 | } | ||
82 | break; | 129 | break; |
83 | case SND_AK4529: | 130 | case SND_AK4529: |
84 | /* FIXME: needed for ak4529? */ | 131 | /* FIXME: needed for ak4529? */ |
85 | break; | 132 | break; |
86 | case SND_AK4355: | 133 | case SND_AK4355: |
87 | case SND_AK4358: | 134 | case SND_AK4358: |
88 | if (state) { | 135 | ak4355_reset(ak, state); |
89 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
90 | return; | ||
91 | } | ||
92 | for (reg = 0x00; reg < 0x0b; reg++) | ||
93 | if (reg != 0x01) | ||
94 | snd_akm4xxx_write(ak, 0, reg, snd_akm4xxx_get(ak, 0, reg)); | ||
95 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
96 | break; | 136 | break; |
97 | case SND_AK4381: | 137 | case SND_AK4381: |
98 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 138 | ak4381_reset(ak, state); |
99 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
100 | if (state) | ||
101 | continue; | ||
102 | for (reg = 0x01; reg < 0x05; reg++) | ||
103 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
104 | } | ||
105 | break; | 139 | break; |
106 | } | 140 | } |
107 | } | 141 | } |
108 | 142 | ||
143 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
144 | |||
109 | /* | 145 | /* |
110 | * initialize all the ak4xxx chips | 146 | * initialize all the ak4xxx chips |
111 | */ | 147 | */ |
@@ -153,7 +189,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
153 | }; | 189 | }; |
154 | static unsigned char inits_ak4355[] = { | 190 | static unsigned char inits_ak4355[] = { |
155 | 0x01, 0x02, /* 1: reset and soft-mute */ | 191 | 0x01, 0x02, /* 1: reset and soft-mute */ |
156 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 192 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
193 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
157 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 194 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
158 | // 0x02, 0x2e, /* quad speed */ | 195 | // 0x02, 0x2e, /* quad speed */ |
159 | 0x03, 0x01, /* 3: de-emphasis off */ | 196 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -169,7 +206,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
169 | }; | 206 | }; |
170 | static unsigned char inits_ak4358[] = { | 207 | static unsigned char inits_ak4358[] = { |
171 | 0x01, 0x02, /* 1: reset and soft-mute */ | 208 | 0x01, 0x02, /* 1: reset and soft-mute */ |
172 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 209 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
210 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
173 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 211 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
174 | // 0x02, 0x2e, /* quad speed */ | 212 | // 0x02, 0x2e, /* quad speed */ |
175 | 0x03, 0x01, /* 3: de-emphasis off */ | 213 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -187,7 +225,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
187 | }; | 225 | }; |
188 | static unsigned char inits_ak4381[] = { | 226 | static unsigned char inits_ak4381[] = { |
189 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ | 227 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ |
190 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */ | 228 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, |
229 | * sharp roll-off, DZF off */ | ||
191 | // 0x01, 0x12, /* quad speed */ | 230 | // 0x01, 0x12, /* quad speed */ |
192 | 0x02, 0x00, /* 2: DZF disabled */ | 231 | 0x02, 0x00, /* 2: DZF disabled */ |
193 | 0x03, 0x00, /* 3: LATT 0 */ | 232 | 0x03, 0x00, /* 3: LATT 0 */ |
@@ -239,12 +278,15 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
239 | } | 278 | } |
240 | } | 279 | } |
241 | 280 | ||
281 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
282 | |||
242 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) | 283 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) |
243 | #define AK_GET_ADDR(val) ((val) & 0xff) | 284 | #define AK_GET_ADDR(val) ((val) & 0xff) |
244 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) | 285 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) |
245 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) | 286 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) |
246 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) | 287 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) |
247 | #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | 288 | #define AK_COMPOSE(chip,addr,shift,mask) \ |
289 | (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | ||
248 | #define AK_INVERT (1<<23) | 290 | #define AK_INVERT (1<<23) |
249 | 291 | ||
250 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, | 292 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, |
@@ -293,7 +335,7 @@ static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol, | |||
293 | } | 335 | } |
294 | 336 | ||
295 | static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol, | 337 | static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol, |
296 | struct snd_ctl_elem_info *uinfo) | 338 | struct snd_ctl_elem_info *uinfo) |
297 | { | 339 | { |
298 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | 340 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); |
299 | 341 | ||
@@ -305,7 +347,7 @@ static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol, | |||
305 | } | 347 | } |
306 | 348 | ||
307 | static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol, | 349 | static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol, |
308 | struct snd_ctl_elem_value *ucontrol) | 350 | struct snd_ctl_elem_value *ucontrol) |
309 | { | 351 | { |
310 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 352 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
311 | int chip = AK_GET_CHIP(kcontrol->private_value); | 353 | int chip = AK_GET_CHIP(kcontrol->private_value); |
@@ -323,7 +365,7 @@ static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol, | |||
323 | } | 365 | } |
324 | 366 | ||
325 | static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, | 367 | static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, |
326 | struct snd_ctl_elem_value *ucontrol) | 368 | struct snd_ctl_elem_value *ucontrol) |
327 | { | 369 | { |
328 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 370 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
329 | int chip = AK_GET_CHIP(kcontrol->private_value); | 371 | int chip = AK_GET_CHIP(kcontrol->private_value); |
@@ -366,7 +408,8 @@ static int snd_akm4xxx_ipga_gain_get(struct snd_kcontrol *kcontrol, | |||
366 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 408 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
367 | int chip = AK_GET_CHIP(kcontrol->private_value); | 409 | int chip = AK_GET_CHIP(kcontrol->private_value); |
368 | int addr = AK_GET_ADDR(kcontrol->private_value); | 410 | int addr = AK_GET_ADDR(kcontrol->private_value); |
369 | ucontrol->value.integer.value[0] = snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | 411 | ucontrol->value.integer.value[0] = |
412 | snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | ||
370 | return 0; | 413 | return 0; |
371 | } | 414 | } |
372 | 415 | ||
@@ -394,7 +437,8 @@ static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, | |||
394 | uinfo->value.enumerated.items = 4; | 437 | uinfo->value.enumerated.items = 4; |
395 | if (uinfo->value.enumerated.item >= 4) | 438 | if (uinfo->value.enumerated.item >= 4) |
396 | uinfo->value.enumerated.item = 3; | 439 | uinfo->value.enumerated.item = 3; |
397 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 440 | strcpy(uinfo->value.enumerated.name, |
441 | texts[uinfo->value.enumerated.item]); | ||
398 | return 0; | 442 | return 0; |
399 | } | 443 | } |
400 | 444 | ||
@@ -405,7 +449,8 @@ static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, | |||
405 | int chip = AK_GET_CHIP(kcontrol->private_value); | 449 | int chip = AK_GET_CHIP(kcontrol->private_value); |
406 | int addr = AK_GET_ADDR(kcontrol->private_value); | 450 | int addr = AK_GET_ADDR(kcontrol->private_value); |
407 | int shift = AK_GET_SHIFT(kcontrol->private_value); | 451 | int shift = AK_GET_SHIFT(kcontrol->private_value); |
408 | ucontrol->value.enumerated.item[0] = (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | 452 | ucontrol->value.enumerated.item[0] = |
453 | (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | ||
409 | return 0; | 454 | return 0; |
410 | } | 455 | } |
411 | 456 | ||
@@ -419,7 +464,8 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol, | |||
419 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; | 464 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; |
420 | int change; | 465 | int change; |
421 | 466 | ||
422 | nval = (nval << shift) | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | 467 | nval = (nval << shift) | |
468 | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | ||
423 | change = snd_akm4xxx_get(ak, chip, addr) != nval; | 469 | change = snd_akm4xxx_get(ak, chip, addr) != nval; |
424 | if (change) | 470 | if (change) |
425 | snd_akm4xxx_write(ak, chip, addr, nval); | 471 | snd_akm4xxx_write(ak, chip, addr, nval); |
@@ -451,7 +497,7 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
451 | } else { | 497 | } else { |
452 | strcpy(ctl->id.name, ak->channel_names[mixer_ch]); | 498 | strcpy(ctl->id.name, ak->channel_names[mixer_ch]); |
453 | num_stereo = ak->num_stereo[mixer_ch]; | 499 | num_stereo = ak->num_stereo[mixer_ch]; |
454 | ctl->id.index = 0; //mixer_ch + ak->idx_offset * 2; | 500 | ctl->id.index = 0; |
455 | } | 501 | } |
456 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 502 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
457 | ctl->count = 1; | 503 | ctl->count = 1; |
@@ -466,27 +512,40 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
466 | } | 512 | } |
467 | switch (ak->type) { | 513 | switch (ak->type) { |
468 | case SND_AK4524: | 514 | case SND_AK4524: |
469 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */ | 515 | /* register 6 & 7 */ |
516 | ctl->private_value = | ||
517 | AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); | ||
470 | break; | 518 | break; |
471 | case SND_AK4528: | 519 | case SND_AK4528: |
472 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 520 | /* register 4 & 5 */ |
521 | ctl->private_value = | ||
522 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
473 | break; | 523 | break; |
474 | case SND_AK4529: { | 524 | case SND_AK4529: { |
475 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */ | 525 | /* registers 2-7 and b,c */ |
476 | ctl->private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | 526 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; |
527 | ctl->private_value = | ||
528 | AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | ||
477 | break; | 529 | break; |
478 | } | 530 | } |
479 | case SND_AK4355: | 531 | case SND_AK4355: |
480 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 532 | /* register 4-9, chip #0 only */ |
533 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); | ||
481 | break; | 534 | break; |
482 | case SND_AK4358: | 535 | case SND_AK4358: |
483 | if (idx >= 6) | 536 | if (idx >= 6) |
484 | ctl->private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */ | 537 | /* register 4-9, chip #0 only */ |
538 | ctl->private_value = | ||
539 | AK_COMPOSE(0, idx + 5, 0, 255); | ||
485 | else | 540 | else |
486 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 541 | /* register 4-9, chip #0 only */ |
542 | ctl->private_value = | ||
543 | AK_COMPOSE(0, idx + 4, 0, 255); | ||
487 | break; | 544 | break; |
488 | case SND_AK4381: | 545 | case SND_AK4381: |
489 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */ | 546 | /* register 3 & 4 */ |
547 | ctl->private_value = | ||
548 | AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); | ||
490 | break; | 549 | break; |
491 | default: | 550 | default: |
492 | err = -EINVAL; | 551 | err = -EINVAL; |
@@ -494,7 +553,10 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
494 | } | 553 | } |
495 | 554 | ||
496 | ctl->private_data = ak; | 555 | ctl->private_data = ak; |
497 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 556 | err = snd_ctl_add(ak->card, |
557 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
558 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
559 | if (err < 0) | ||
498 | goto __error; | 560 | goto __error; |
499 | 561 | ||
500 | idx += num_stereo; | 562 | idx += num_stereo; |
@@ -509,9 +571,14 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
509 | ctl->info = snd_akm4xxx_volume_info; | 571 | ctl->info = snd_akm4xxx_volume_info; |
510 | ctl->get = snd_akm4xxx_volume_get; | 572 | ctl->get = snd_akm4xxx_volume_get; |
511 | ctl->put = snd_akm4xxx_volume_put; | 573 | ctl->put = snd_akm4xxx_volume_put; |
512 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 574 | /* register 4 & 5 */ |
575 | ctl->private_value = | ||
576 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
513 | ctl->private_data = ak; | 577 | ctl->private_data = ak; |
514 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 578 | err = snd_ctl_add(ak->card, |
579 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
580 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
581 | if (err < 0) | ||
515 | goto __error; | 582 | goto __error; |
516 | 583 | ||
517 | memset(ctl, 0, sizeof(*ctl)); | 584 | memset(ctl, 0, sizeof(*ctl)); |
@@ -522,9 +589,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
522 | ctl->info = snd_akm4xxx_ipga_gain_info; | 589 | ctl->info = snd_akm4xxx_ipga_gain_info; |
523 | ctl->get = snd_akm4xxx_ipga_gain_get; | 590 | ctl->get = snd_akm4xxx_ipga_gain_get; |
524 | ctl->put = snd_akm4xxx_ipga_gain_put; | 591 | ctl->put = snd_akm4xxx_ipga_gain_put; |
525 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */ | 592 | /* register 4 & 5 */ |
593 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); | ||
526 | ctl->private_data = ak; | 594 | ctl->private_data = ak; |
527 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 595 | err = snd_ctl_add(ak->card, |
596 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
597 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
598 | if (err < 0) | ||
528 | goto __error; | 599 | goto __error; |
529 | } | 600 | } |
530 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) | 601 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) |
@@ -543,11 +614,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
543 | switch (ak->type) { | 614 | switch (ak->type) { |
544 | case SND_AK4524: | 615 | case SND_AK4524: |
545 | case SND_AK4528: | 616 | case SND_AK4528: |
546 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */ | 617 | /* register 3 */ |
618 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); | ||
547 | break; | 619 | break; |
548 | case SND_AK4529: { | 620 | case SND_AK4529: { |
549 | int shift = idx == 3 ? 6 : (2 - idx) * 2; | 621 | int shift = idx == 3 ? 6 : (2 - idx) * 2; |
550 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */ | 622 | /* register 8 with shift */ |
623 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); | ||
551 | break; | 624 | break; |
552 | } | 625 | } |
553 | case SND_AK4355: | 626 | case SND_AK4355: |
@@ -559,7 +632,10 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
559 | break; | 632 | break; |
560 | } | 633 | } |
561 | ctl->private_data = ak; | 634 | ctl->private_data = ak; |
562 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 635 | err = snd_ctl_add(ak->card, |
636 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
637 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
638 | if (err < 0) | ||
563 | goto __error; | 639 | goto __error; |
564 | } | 640 | } |
565 | err = 0; | 641 | err = 0; |
@@ -569,6 +645,8 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
569 | return err; | 645 | return err; |
570 | } | 646 | } |
571 | 647 | ||
648 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||
649 | |||
572 | static int __init alsa_akm4xxx_module_init(void) | 650 | static int __init alsa_akm4xxx_module_init(void) |
573 | { | 651 | { |
574 | return 0; | 652 | return 0; |
@@ -580,8 +658,3 @@ static void __exit alsa_akm4xxx_module_exit(void) | |||
580 | 658 | ||
581 | module_init(alsa_akm4xxx_module_init) | 659 | module_init(alsa_akm4xxx_module_init) |
582 | module_exit(alsa_akm4xxx_module_exit) | 660 | module_exit(alsa_akm4xxx_module_exit) |
583 | |||
584 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
585 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
586 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
587 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||