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); | ||
