aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712/ice1724.c
diff options
context:
space:
mode:
authorPavel Hofman <pavel.hofman@ivitera.com>2009-09-16 16:25:40 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-21 09:48:00 -0400
commit1ff97cb9dd9f53b33ce6710a4f861f43e70e8ca4 (patch)
treeb368fa7a43d062940e5fb29c31b609b16bc7bd9d /sound/pci/ice1712/ice1724.c
parent6796d5a05f4d3caad17d2586b3e5776fda50ef82 (diff)
ALSA: ice1724 - Support for multiple external clock types
* Support for customization of the external clock names * Adding hooks to playback_pro_open and capture_pro_open, allowing e.g. limiting available stream rates to a single value when the external clock rate is detected Signed-off-by: Pavel Hofman <pavel.hofman@ivitera.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ice1712/ice1724.c')
-rw-r--r--sound/pci/ice1712/ice1724.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 514e15385f7a..3f11195b2631 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -104,6 +104,8 @@ static int PRO_RATE_LOCKED;
104static int PRO_RATE_RESET = 1; 104static int PRO_RATE_RESET = 1;
105static unsigned int PRO_RATE_DEFAULT = 44100; 105static unsigned int PRO_RATE_DEFAULT = 44100;
106 106
107static char *ext_clock_names[1] = { "IEC958 In" };
108
107/* 109/*
108 * Basic I/O 110 * Basic I/O
109 */ 111 */
@@ -1042,6 +1044,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1042 VT1724_BUFFER_ALIGN); 1044 VT1724_BUFFER_ALIGN);
1043 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1045 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1044 VT1724_BUFFER_ALIGN); 1046 VT1724_BUFFER_ALIGN);
1047 if (ice->pro_open)
1048 ice->pro_open(ice, substream);
1045 return 0; 1049 return 0;
1046} 1050}
1047 1051
@@ -1060,6 +1064,8 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1060 VT1724_BUFFER_ALIGN); 1064 VT1724_BUFFER_ALIGN);
1061 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1065 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1062 VT1724_BUFFER_ALIGN); 1066 VT1724_BUFFER_ALIGN);
1067 if (ice->pro_open)
1068 ice->pro_open(ice, substream);
1063 return 0; 1069 return 0;
1064} 1070}
1065 1071
@@ -1813,15 +1819,21 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1813 struct snd_ctl_elem_info *uinfo) 1819 struct snd_ctl_elem_info *uinfo)
1814{ 1820{
1815 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1821 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1816 1822 int hw_rates_count = ice->hw_rates->count;
1817 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1823 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1818 uinfo->count = 1; 1824 uinfo->count = 1;
1819 uinfo->value.enumerated.items = ice->hw_rates->count + 1; 1825
1826 uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count;
1827 /* upper limit - keep at top */
1820 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1828 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1821 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1829 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1822 if (uinfo->value.enumerated.item == uinfo->value.enumerated.items - 1) 1830 if (uinfo->value.enumerated.item >= hw_rates_count)
1823 strcpy(uinfo->value.enumerated.name, "IEC958 Input"); 1831 /* ext_clock items */
1832 strcpy(uinfo->value.enumerated.name,
1833 ice->ext_clock_names[
1834 uinfo->value.enumerated.item - hw_rates_count]);
1824 else 1835 else
1836 /* int clock items */
1825 sprintf(uinfo->value.enumerated.name, "%d", 1837 sprintf(uinfo->value.enumerated.name, "%d",
1826 ice->hw_rates->list[uinfo->value.enumerated.item]); 1838 ice->hw_rates->list[uinfo->value.enumerated.item]);
1827 return 0; 1839 return 0;
@@ -1835,7 +1847,8 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1835 1847
1836 spin_lock_irq(&ice->reg_lock); 1848 spin_lock_irq(&ice->reg_lock);
1837 if (ice->is_spdif_master(ice)) { 1849 if (ice->is_spdif_master(ice)) {
1838 ucontrol->value.enumerated.item[0] = ice->hw_rates->count; 1850 ucontrol->value.enumerated.item[0] = ice->hw_rates->count +
1851 ice->get_spdif_master_type(ice);
1839 } else { 1852 } else {
1840 rate = ice->get_rate(ice); 1853 rate = ice->get_rate(ice);
1841 ucontrol->value.enumerated.item[0] = 0; 1854 ucontrol->value.enumerated.item[0] = 0;
@@ -1850,8 +1863,14 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1850 return 0; 1863 return 0;
1851} 1864}
1852 1865
1866static int stdclock_get_spdif_master_type(struct snd_ice1712 *ice)
1867{
1868 /* standard external clock - only single type - SPDIF IN */
1869 return 0;
1870}
1871
1853/* setting clock to external - SPDIF */ 1872/* setting clock to external - SPDIF */
1854static void stdclock_set_spdif_clock(struct snd_ice1712 *ice) 1873static int stdclock_set_spdif_clock(struct snd_ice1712 *ice, int type)
1855{ 1874{
1856 unsigned char oval; 1875 unsigned char oval;
1857 unsigned char i2s_oval; 1876 unsigned char i2s_oval;
@@ -1860,27 +1879,30 @@ static void stdclock_set_spdif_clock(struct snd_ice1712 *ice)
1860 /* setting 256fs */ 1879 /* setting 256fs */
1861 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); 1880 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
1862 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT)); 1881 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT));
1882 return 0;
1863} 1883}
1864 1884
1885
1865static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, 1886static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1866 struct snd_ctl_elem_value *ucontrol) 1887 struct snd_ctl_elem_value *ucontrol)
1867{ 1888{
1868 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1889 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1869 unsigned int old_rate, new_rate; 1890 unsigned int old_rate, new_rate;
1870 unsigned int item = ucontrol->value.enumerated.item[0]; 1891 unsigned int item = ucontrol->value.enumerated.item[0];
1871 unsigned int spdif = ice->hw_rates->count; 1892 unsigned int first_ext_clock = ice->hw_rates->count;
1872 1893
1873 if (item > spdif) 1894 if (item > first_ext_clock + ice->ext_clock_count - 1)
1874 return -EINVAL; 1895 return -EINVAL;
1875 1896
1897 /* if rate = 0 => external clock */
1876 spin_lock_irq(&ice->reg_lock); 1898 spin_lock_irq(&ice->reg_lock);
1877 if (ice->is_spdif_master(ice)) 1899 if (ice->is_spdif_master(ice))
1878 old_rate = 0; 1900 old_rate = 0;
1879 else 1901 else
1880 old_rate = ice->get_rate(ice); 1902 old_rate = ice->get_rate(ice);
1881 if (item == spdif) { 1903 if (item >= first_ext_clock) {
1882 /* switching to external clock via SPDIF */ 1904 /* switching to external clock */
1883 ice->set_spdif_clock(ice); 1905 ice->set_spdif_clock(ice, item - first_ext_clock);
1884 new_rate = 0; 1906 new_rate = 0;
1885 } else { 1907 } else {
1886 /* internal on-card clock */ 1908 /* internal on-card clock */
@@ -1892,7 +1914,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1892 } 1914 }
1893 spin_unlock_irq(&ice->reg_lock); 1915 spin_unlock_irq(&ice->reg_lock);
1894 1916
1895 /* the first reset to the SPDIF master mode? */ 1917 /* the first switch to the ext. clock mode? */
1896 if (old_rate != new_rate && !new_rate) { 1918 if (old_rate != new_rate && !new_rate) {
1897 /* notify akm chips as well */ 1919 /* notify akm chips as well */
1898 unsigned int i; 1920 unsigned int i;
@@ -2550,6 +2572,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2550 return err; 2572 return err;
2551 } 2573 }
2552 2574
2575 /* field init before calling chip_init */
2576 ice->ext_clock_count = 0;
2577
2553 for (tbl = card_tables; *tbl; tbl++) { 2578 for (tbl = card_tables; *tbl; tbl++) {
2554 for (c = *tbl; c->subvendor; c++) { 2579 for (c = *tbl; c->subvendor; c++) {
2555 if (c->subvendor == ice->eeprom.subvendor) { 2580 if (c->subvendor == ice->eeprom.subvendor) {
@@ -2588,6 +2613,13 @@ __found:
2588 ice->set_mclk = stdclock_set_mclk; 2613 ice->set_mclk = stdclock_set_mclk;
2589 if (!ice->set_spdif_clock) 2614 if (!ice->set_spdif_clock)
2590 ice->set_spdif_clock = stdclock_set_spdif_clock; 2615 ice->set_spdif_clock = stdclock_set_spdif_clock;
2616 if (!ice->get_spdif_master_type)
2617 ice->get_spdif_master_type = stdclock_get_spdif_master_type;
2618 if (!ice->ext_clock_names)
2619 ice->ext_clock_names = ext_clock_names;
2620 if (!ice->ext_clock_count)
2621 ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
2622
2591 if (!ice->hw_rates) 2623 if (!ice->hw_rates)
2592 set_std_hw_rates(ice); 2624 set_std_hw_rates(ice);
2593 2625
@@ -2747,7 +2779,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2747 2779
2748 if (ice->pm_saved_is_spdif_master) { 2780 if (ice->pm_saved_is_spdif_master) {
2749 /* switching to external clock via SPDIF */ 2781 /* switching to external clock via SPDIF */
2750 ice->set_spdif_clock(ice); 2782 ice->set_spdif_clock(ice, 0);
2751 } else { 2783 } else {
2752 /* internal on-card clock */ 2784 /* internal on-card clock */
2753 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); 2785 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);