aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712/ice1724.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-12-01 09:57:01 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-01 09:57:01 -0500
commit980f31c46b3c7895ad926fbb43c8edac6ce193ff (patch)
treeec61a87b42ce8e6eb24554d8a56173ef75aefdd2 /sound/pci/ice1712/ice1724.c
parent9e298f449e667833c4cafad040ce8025a8ba1eed (diff)
parent6ef80706184be792499a4485a7957f2660b6a076 (diff)
Merge branch 'topic/ice1724-quartet' into topic/hda
Diffstat (limited to 'sound/pci/ice1712/ice1724.c')
-rw-r--r--sound/pci/ice1712/ice1724.c103
1 files changed, 83 insertions, 20 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 10fc92c05574..ae29073eea93 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -53,6 +53,7 @@
53#include "phase.h" 53#include "phase.h"
54#include "wtm.h" 54#include "wtm.h"
55#include "se.h" 55#include "se.h"
56#include "quartet.h"
56 57
57MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 58MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
58MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); 59MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -70,6 +71,7 @@ MODULE_SUPPORTED_DEVICE("{"
70 PHASE_DEVICE_DESC 71 PHASE_DEVICE_DESC
71 WTM_DEVICE_DESC 72 WTM_DEVICE_DESC
72 SE_DEVICE_DESC 73 SE_DEVICE_DESC
74 QTET_DEVICE_DESC
73 "{VIA,VT1720}," 75 "{VIA,VT1720},"
74 "{VIA,VT1724}," 76 "{VIA,VT1724},"
75 "{ICEnsemble,Generic ICE1724}," 77 "{ICEnsemble,Generic ICE1724},"
@@ -104,6 +106,8 @@ static int PRO_RATE_LOCKED;
104static int PRO_RATE_RESET = 1; 106static int PRO_RATE_RESET = 1;
105static unsigned int PRO_RATE_DEFAULT = 44100; 107static unsigned int PRO_RATE_DEFAULT = 44100;
106 108
109static char *ext_clock_names[1] = { "IEC958 In" };
110
107/* 111/*
108 * Basic I/O 112 * Basic I/O
109 */ 113 */
@@ -118,9 +122,12 @@ static inline int stdclock_is_spdif_master(struct snd_ice1712 *ice)
118 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0; 122 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
119} 123}
120 124
125/*
126 * locking rate makes sense only for internal clock mode
127 */
121static inline int is_pro_rate_locked(struct snd_ice1712 *ice) 128static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
122{ 129{
123 return ice->is_spdif_master(ice) || PRO_RATE_LOCKED; 130 return (!ice->is_spdif_master(ice)) && PRO_RATE_LOCKED;
124} 131}
125 132
126/* 133/*
@@ -196,6 +203,12 @@ static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
196 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */ 203 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
197} 204}
198 205
206/* get gpio direction 0 = read, 1 = write */
207static unsigned int snd_vt1724_get_gpio_dir(struct snd_ice1712 *ice)
208{
209 return inl(ICEREG1724(ice, GPIO_DIRECTION));
210}
211
199/* set the gpio mask (0 = writable) */ 212/* set the gpio mask (0 = writable) */
200static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) 213static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
201{ 214{
@@ -205,6 +218,17 @@ static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
205 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */ 218 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
206} 219}
207 220
221static unsigned int snd_vt1724_get_gpio_mask(struct snd_ice1712 *ice)
222{
223 unsigned int mask;
224 if (!ice->vt1720)
225 mask = (unsigned int)inb(ICEREG1724(ice, GPIO_WRITE_MASK_22));
226 else
227 mask = 0;
228 mask = (mask << 16) | inw(ICEREG1724(ice, GPIO_WRITE_MASK));
229 return mask;
230}
231
208static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) 232static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
209{ 233{
210 outw(data, ICEREG1724(ice, GPIO_DATA)); 234 outw(data, ICEREG1724(ice, GPIO_DATA));
@@ -651,16 +675,22 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
651 return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY; 675 return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
652 } 676 }
653 if (!force && is_pro_rate_locked(ice)) { 677 if (!force && is_pro_rate_locked(ice)) {
678 /* comparing required and current rate - makes sense for
679 * internal clock only */
654 spin_unlock_irqrestore(&ice->reg_lock, flags); 680 spin_unlock_irqrestore(&ice->reg_lock, flags);
655 return (rate == ice->cur_rate) ? 0 : -EBUSY; 681 return (rate == ice->cur_rate) ? 0 : -EBUSY;
656 } 682 }
657 683
658 old_rate = ice->get_rate(ice); 684 if (force || !ice->is_spdif_master(ice)) {
659 if (force || (old_rate != rate)) 685 /* force means the rate was switched by ucontrol, otherwise
660 ice->set_rate(ice, rate); 686 * setting clock rate for internal clock mode */
661 else if (rate == ice->cur_rate) { 687 old_rate = ice->get_rate(ice);
662 spin_unlock_irqrestore(&ice->reg_lock, flags); 688 if (force || (old_rate != rate))
663 return 0; 689 ice->set_rate(ice, rate);
690 else if (rate == ice->cur_rate) {
691 spin_unlock_irqrestore(&ice->reg_lock, flags);
692 return 0;
693 }
664 } 694 }
665 695
666 ice->cur_rate = rate; 696 ice->cur_rate = rate;
@@ -1016,6 +1046,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1016 VT1724_BUFFER_ALIGN); 1046 VT1724_BUFFER_ALIGN);
1017 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1018 VT1724_BUFFER_ALIGN); 1048 VT1724_BUFFER_ALIGN);
1049 if (ice->pro_open)
1050 ice->pro_open(ice, substream);
1019 return 0; 1051 return 0;
1020} 1052}
1021 1053
@@ -1034,6 +1066,8 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1034 VT1724_BUFFER_ALIGN); 1066 VT1724_BUFFER_ALIGN);
1035 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1036 VT1724_BUFFER_ALIGN); 1068 VT1724_BUFFER_ALIGN);
1069 if (ice->pro_open)
1070 ice->pro_open(ice, substream);
1037 return 0; 1071 return 0;
1038} 1072}
1039 1073
@@ -1787,15 +1821,21 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1787 struct snd_ctl_elem_info *uinfo) 1821 struct snd_ctl_elem_info *uinfo)
1788{ 1822{
1789 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1823 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1790 1824 int hw_rates_count = ice->hw_rates->count;
1791 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1825 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1792 uinfo->count = 1; 1826 uinfo->count = 1;
1793 uinfo->value.enumerated.items = ice->hw_rates->count + 1; 1827
1828 uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count;
1829 /* upper limit - keep at top */
1794 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1830 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1795 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1831 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1796 if (uinfo->value.enumerated.item == uinfo->value.enumerated.items - 1) 1832 if (uinfo->value.enumerated.item >= hw_rates_count)
1797 strcpy(uinfo->value.enumerated.name, "IEC958 Input"); 1833 /* ext_clock items */
1834 strcpy(uinfo->value.enumerated.name,
1835 ice->ext_clock_names[
1836 uinfo->value.enumerated.item - hw_rates_count]);
1798 else 1837 else
1838 /* int clock items */
1799 sprintf(uinfo->value.enumerated.name, "%d", 1839 sprintf(uinfo->value.enumerated.name, "%d",
1800 ice->hw_rates->list[uinfo->value.enumerated.item]); 1840 ice->hw_rates->list[uinfo->value.enumerated.item]);
1801 return 0; 1841 return 0;
@@ -1809,7 +1849,8 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1809 1849
1810 spin_lock_irq(&ice->reg_lock); 1850 spin_lock_irq(&ice->reg_lock);
1811 if (ice->is_spdif_master(ice)) { 1851 if (ice->is_spdif_master(ice)) {
1812 ucontrol->value.enumerated.item[0] = ice->hw_rates->count; 1852 ucontrol->value.enumerated.item[0] = ice->hw_rates->count +
1853 ice->get_spdif_master_type(ice);
1813 } else { 1854 } else {
1814 rate = ice->get_rate(ice); 1855 rate = ice->get_rate(ice);
1815 ucontrol->value.enumerated.item[0] = 0; 1856 ucontrol->value.enumerated.item[0] = 0;
@@ -1824,8 +1865,14 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1824 return 0; 1865 return 0;
1825} 1866}
1826 1867
1868static int stdclock_get_spdif_master_type(struct snd_ice1712 *ice)
1869{
1870 /* standard external clock - only single type - SPDIF IN */
1871 return 0;
1872}
1873
1827/* setting clock to external - SPDIF */ 1874/* setting clock to external - SPDIF */
1828static void stdclock_set_spdif_clock(struct snd_ice1712 *ice) 1875static int stdclock_set_spdif_clock(struct snd_ice1712 *ice, int type)
1829{ 1876{
1830 unsigned char oval; 1877 unsigned char oval;
1831 unsigned char i2s_oval; 1878 unsigned char i2s_oval;
@@ -1834,27 +1881,30 @@ static void stdclock_set_spdif_clock(struct snd_ice1712 *ice)
1834 /* setting 256fs */ 1881 /* setting 256fs */
1835 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); 1882 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
1836 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT)); 1883 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT));
1884 return 0;
1837} 1885}
1838 1886
1887
1839static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, 1888static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1840 struct snd_ctl_elem_value *ucontrol) 1889 struct snd_ctl_elem_value *ucontrol)
1841{ 1890{
1842 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1891 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1843 unsigned int old_rate, new_rate; 1892 unsigned int old_rate, new_rate;
1844 unsigned int item = ucontrol->value.enumerated.item[0]; 1893 unsigned int item = ucontrol->value.enumerated.item[0];
1845 unsigned int spdif = ice->hw_rates->count; 1894 unsigned int first_ext_clock = ice->hw_rates->count;
1846 1895
1847 if (item > spdif) 1896 if (item > first_ext_clock + ice->ext_clock_count - 1)
1848 return -EINVAL; 1897 return -EINVAL;
1849 1898
1899 /* if rate = 0 => external clock */
1850 spin_lock_irq(&ice->reg_lock); 1900 spin_lock_irq(&ice->reg_lock);
1851 if (ice->is_spdif_master(ice)) 1901 if (ice->is_spdif_master(ice))
1852 old_rate = 0; 1902 old_rate = 0;
1853 else 1903 else
1854 old_rate = ice->get_rate(ice); 1904 old_rate = ice->get_rate(ice);
1855 if (item == spdif) { 1905 if (item >= first_ext_clock) {
1856 /* switching to external clock via SPDIF */ 1906 /* switching to external clock */
1857 ice->set_spdif_clock(ice); 1907 ice->set_spdif_clock(ice, item - first_ext_clock);
1858 new_rate = 0; 1908 new_rate = 0;
1859 } else { 1909 } else {
1860 /* internal on-card clock */ 1910 /* internal on-card clock */
@@ -1866,7 +1916,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1866 } 1916 }
1867 spin_unlock_irq(&ice->reg_lock); 1917 spin_unlock_irq(&ice->reg_lock);
1868 1918
1869 /* the first reset to the SPDIF master mode? */ 1919 /* the first switch to the ext. clock mode? */
1870 if (old_rate != new_rate && !new_rate) { 1920 if (old_rate != new_rate && !new_rate) {
1871 /* notify akm chips as well */ 1921 /* notify akm chips as well */
1872 unsigned int i; 1922 unsigned int i;
@@ -2136,6 +2186,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2136 snd_vt1724_phase_cards, 2186 snd_vt1724_phase_cards,
2137 snd_vt1724_wtm_cards, 2187 snd_vt1724_wtm_cards,
2138 snd_vt1724_se_cards, 2188 snd_vt1724_se_cards,
2189 snd_vt1724_qtet_cards,
2139 NULL, 2190 NULL,
2140}; 2191};
2141 2192
@@ -2434,7 +2485,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2434 mutex_init(&ice->open_mutex); 2485 mutex_init(&ice->open_mutex);
2435 mutex_init(&ice->i2c_mutex); 2486 mutex_init(&ice->i2c_mutex);
2436 ice->gpio.set_mask = snd_vt1724_set_gpio_mask; 2487 ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
2488 ice->gpio.get_mask = snd_vt1724_get_gpio_mask;
2437 ice->gpio.set_dir = snd_vt1724_set_gpio_dir; 2489 ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
2490 ice->gpio.get_dir = snd_vt1724_get_gpio_dir;
2438 ice->gpio.set_data = snd_vt1724_set_gpio_data; 2491 ice->gpio.set_data = snd_vt1724_set_gpio_data;
2439 ice->gpio.get_data = snd_vt1724_get_gpio_data; 2492 ice->gpio.get_data = snd_vt1724_get_gpio_data;
2440 ice->card = card; 2493 ice->card = card;
@@ -2522,6 +2575,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2522 return err; 2575 return err;
2523 } 2576 }
2524 2577
2578 /* field init before calling chip_init */
2579 ice->ext_clock_count = 0;
2580
2525 for (tbl = card_tables; *tbl; tbl++) { 2581 for (tbl = card_tables; *tbl; tbl++) {
2526 for (c = *tbl; c->subvendor; c++) { 2582 for (c = *tbl; c->subvendor; c++) {
2527 if (c->subvendor == ice->eeprom.subvendor) { 2583 if (c->subvendor == ice->eeprom.subvendor) {
@@ -2560,6 +2616,13 @@ __found:
2560 ice->set_mclk = stdclock_set_mclk; 2616 ice->set_mclk = stdclock_set_mclk;
2561 if (!ice->set_spdif_clock) 2617 if (!ice->set_spdif_clock)
2562 ice->set_spdif_clock = stdclock_set_spdif_clock; 2618 ice->set_spdif_clock = stdclock_set_spdif_clock;
2619 if (!ice->get_spdif_master_type)
2620 ice->get_spdif_master_type = stdclock_get_spdif_master_type;
2621 if (!ice->ext_clock_names)
2622 ice->ext_clock_names = ext_clock_names;
2623 if (!ice->ext_clock_count)
2624 ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
2625
2563 if (!ice->hw_rates) 2626 if (!ice->hw_rates)
2564 set_std_hw_rates(ice); 2627 set_std_hw_rates(ice);
2565 2628
@@ -2719,7 +2782,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2719 2782
2720 if (ice->pm_saved_is_spdif_master) { 2783 if (ice->pm_saved_is_spdif_master) {
2721 /* switching to external clock via SPDIF */ 2784 /* switching to external clock via SPDIF */
2722 ice->set_spdif_clock(ice); 2785 ice->set_spdif_clock(ice, 0);
2723 } else { 2786 } else {
2724 /* internal on-card clock */ 2787 /* internal on-card clock */
2725 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); 2788 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);