diff options
Diffstat (limited to 'sound/pci/ice1712/delta.c')
-rw-r--r-- | sound/pci/ice1712/delta.c | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 9a51d34e6817..af659800c9b0 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/mutex.h> | ||
32 | |||
31 | #include <sound/core.h> | 33 | #include <sound/core.h> |
32 | #include <sound/cs8427.h> | 34 | #include <sound/cs8427.h> |
33 | #include <sound/asoundef.h> | 35 | #include <sound/asoundef.h> |
@@ -130,13 +132,13 @@ static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *byt | |||
130 | int res = count; | 132 | int res = count; |
131 | unsigned char tmp; | 133 | unsigned char tmp; |
132 | 134 | ||
133 | down(&ice->gpio_mutex); | 135 | mutex_lock(&ice->gpio_mutex); |
134 | tmp = ap_cs8427_codec_select(ice); | 136 | tmp = ap_cs8427_codec_select(ice); |
135 | ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ | 137 | ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ |
136 | while (count-- > 0) | 138 | while (count-- > 0) |
137 | ap_cs8427_write_byte(ice, *bytes++, tmp); | 139 | ap_cs8427_write_byte(ice, *bytes++, tmp); |
138 | ap_cs8427_codec_deassert(ice, tmp); | 140 | ap_cs8427_codec_deassert(ice, tmp); |
139 | up(&ice->gpio_mutex); | 141 | mutex_unlock(&ice->gpio_mutex); |
140 | return res; | 142 | return res; |
141 | } | 143 | } |
142 | 144 | ||
@@ -147,13 +149,13 @@ static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *byt | |||
147 | int res = count; | 149 | int res = count; |
148 | unsigned char tmp; | 150 | unsigned char tmp; |
149 | 151 | ||
150 | down(&ice->gpio_mutex); | 152 | mutex_lock(&ice->gpio_mutex); |
151 | tmp = ap_cs8427_codec_select(ice); | 153 | tmp = ap_cs8427_codec_select(ice); |
152 | ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ | 154 | ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ |
153 | while (count-- > 0) | 155 | while (count-- > 0) |
154 | *bytes++ = ap_cs8427_read_byte(ice, tmp); | 156 | *bytes++ = ap_cs8427_read_byte(ice, tmp); |
155 | ap_cs8427_codec_deassert(ice, tmp); | 157 | ap_cs8427_codec_deassert(ice, tmp); |
156 | up(&ice->gpio_mutex); | 158 | mutex_unlock(&ice->gpio_mutex); |
157 | return res; | 159 | return res; |
158 | } | 160 | } |
159 | 161 | ||
@@ -180,7 +182,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign | |||
180 | /* send byte to transmitter */ | 182 | /* send byte to transmitter */ |
181 | mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; | 183 | mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; |
182 | mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; | 184 | mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; |
183 | down(&ice->gpio_mutex); | 185 | mutex_lock(&ice->gpio_mutex); |
184 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 186 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
185 | for (idx = 7; idx >= 0; idx--) { | 187 | for (idx = 7; idx >= 0; idx--) { |
186 | tmp &= ~(mask1 | mask2); | 188 | tmp &= ~(mask1 | mask2); |
@@ -194,7 +196,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign | |||
194 | } | 196 | } |
195 | tmp &= ~mask1; | 197 | tmp &= ~mask1; |
196 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); | 198 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); |
197 | up(&ice->gpio_mutex); | 199 | mutex_unlock(&ice->gpio_mutex); |
198 | } | 200 | } |
199 | 201 | ||
200 | 202 | ||
@@ -296,14 +298,14 @@ static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) | |||
296 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ | 298 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ |
297 | return; | 299 | return; |
298 | 300 | ||
299 | down(&ice->gpio_mutex); | 301 | mutex_lock(&ice->gpio_mutex); |
300 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 302 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
301 | tmp2 = tmp & ~ICE1712_DELTA_DFS; | 303 | tmp2 = tmp & ~ICE1712_DELTA_DFS; |
302 | if (rate > 48000) | 304 | if (rate > 48000) |
303 | tmp2 |= ICE1712_DELTA_DFS; | 305 | tmp2 |= ICE1712_DELTA_DFS; |
304 | if (tmp != tmp2) | 306 | if (tmp != tmp2) |
305 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); | 307 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); |
306 | up(&ice->gpio_mutex); | 308 | mutex_unlock(&ice->gpio_mutex); |
307 | } | 309 | } |
308 | 310 | ||
309 | /* | 311 | /* |
@@ -318,9 +320,9 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
318 | return; | 320 | return; |
319 | 321 | ||
320 | /* check before reset ak4524 to avoid unnecessary clicks */ | 322 | /* check before reset ak4524 to avoid unnecessary clicks */ |
321 | down(&ice->gpio_mutex); | 323 | mutex_lock(&ice->gpio_mutex); |
322 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 324 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
323 | up(&ice->gpio_mutex); | 325 | mutex_unlock(&ice->gpio_mutex); |
324 | tmp2 = tmp & ~ICE1712_DELTA_DFS; | 326 | tmp2 = tmp & ~ICE1712_DELTA_DFS; |
325 | if (rate > 48000) | 327 | if (rate > 48000) |
326 | tmp2 |= ICE1712_DELTA_DFS; | 328 | tmp2 |= ICE1712_DELTA_DFS; |
@@ -329,12 +331,12 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
329 | 331 | ||
330 | /* do it again */ | 332 | /* do it again */ |
331 | snd_akm4xxx_reset(ak, 1); | 333 | snd_akm4xxx_reset(ak, 1); |
332 | down(&ice->gpio_mutex); | 334 | mutex_lock(&ice->gpio_mutex); |
333 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; | 335 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; |
334 | if (rate > 48000) | 336 | if (rate > 48000) |
335 | tmp |= ICE1712_DELTA_DFS; | 337 | tmp |= ICE1712_DELTA_DFS; |
336 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); | 338 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); |
337 | up(&ice->gpio_mutex); | 339 | mutex_unlock(&ice->gpio_mutex); |
338 | snd_akm4xxx_reset(ak, 0); | 340 | snd_akm4xxx_reset(ak, 0); |
339 | } | 341 | } |
340 | 342 | ||
@@ -391,6 +393,37 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) | |||
391 | snd_ice1712_delta_cs8403_spdif_write(ice, tmp); | 393 | snd_ice1712_delta_cs8403_spdif_write(ice, tmp); |
392 | } | 394 | } |
393 | 395 | ||
396 | static int snd_ice1712_delta1010lt_wordclock_status_info(struct snd_kcontrol *kcontrol, | ||
397 | struct snd_ctl_elem_info *uinfo) | ||
398 | { | ||
399 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
400 | uinfo->count = 1; | ||
401 | uinfo->value.integer.min = 0; | ||
402 | uinfo->value.integer.max = 1; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, | ||
407 | struct snd_ctl_elem_value *ucontrol) | ||
408 | { | ||
409 | char reg = 0x10; // cs8427 receiver error register | ||
410 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
411 | |||
412 | if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) | ||
413 | snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); | ||
414 | snd_i2c_readbytes(ice->cs8427, ®, 1); | ||
415 | ucontrol->value.integer.value[0] = (reg ? 1 : 0); | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = | ||
420 | { | ||
421 | .access = (SNDRV_CTL_ELEM_ACCESS_READ), | ||
422 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
423 | .name = "Word Clock Status", | ||
424 | .info = snd_ice1712_delta1010lt_wordclock_status_info, | ||
425 | .get = snd_ice1712_delta1010lt_wordclock_status_get, | ||
426 | }; | ||
394 | 427 | ||
395 | /* | 428 | /* |
396 | * initialize the chips on M-Audio cards | 429 | * initialize the chips on M-Audio cards |
@@ -620,7 +653,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) | |||
620 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = | 653 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = |
621 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); | 654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); |
622 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = | 655 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = |
623 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); | 656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); |
624 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = | 657 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = |
625 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 658 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
626 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = | 659 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = |
@@ -653,6 +686,9 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) | |||
653 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); | 686 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); |
654 | if (err < 0) | 687 | if (err < 0) |
655 | return err; | 688 | return err; |
689 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice)); | ||
690 | if (err < 0) | ||
691 | return err; | ||
656 | break; | 692 | break; |
657 | } | 693 | } |
658 | 694 | ||