diff options
Diffstat (limited to 'sound/sparc')
-rw-r--r-- | sound/sparc/cs4231.c | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index e2be131723ed..271b0420f8be 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for CS4231 sound chips found on Sparcs. | 2 | * Driver for CS4231 sound chips found on Sparcs. |
3 | * Copyright (C) 2002 David S. Miller <davem@redhat.com> | 3 | * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net> |
4 | * | 4 | * |
5 | * Based entirely upon drivers/sbus/audio/cs4231.c which is: | 5 | * Based entirely upon drivers/sbus/audio/cs4231.c which is: |
6 | * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) | 6 | * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) |
@@ -17,7 +17,8 @@ | |||
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | #include <linux/of.h> | |
21 | #include <linux/of_device.h> | ||
21 | 22 | ||
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
@@ -29,7 +30,6 @@ | |||
29 | 30 | ||
30 | #ifdef CONFIG_SBUS | 31 | #ifdef CONFIG_SBUS |
31 | #define SBUS_SUPPORT | 32 | #define SBUS_SUPPORT |
32 | #include <asm/sbus.h> | ||
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) | 35 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) |
@@ -116,7 +116,7 @@ struct snd_cs4231 { | |||
116 | 116 | ||
117 | union { | 117 | union { |
118 | #ifdef SBUS_SUPPORT | 118 | #ifdef SBUS_SUPPORT |
119 | struct sbus_dev *sdev; | 119 | struct of_device *op; |
120 | #endif | 120 | #endif |
121 | #ifdef EBUS_SUPPORT | 121 | #ifdef EBUS_SUPPORT |
122 | struct pci_dev *pdev; | 122 | struct pci_dev *pdev; |
@@ -1785,7 +1785,7 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) | |||
1785 | static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) | 1785 | static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) |
1786 | { | 1786 | { |
1787 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1787 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1788 | &chip->dev_u.sdev->ofdev.dev, | 1788 | &chip->dev_u.op->dev, |
1789 | 64 * 1024, 128 * 1024); | 1789 | 64 * 1024, 128 * 1024); |
1790 | } | 1790 | } |
1791 | 1791 | ||
@@ -1795,11 +1795,13 @@ static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) | |||
1795 | 1795 | ||
1796 | static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) | 1796 | static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) |
1797 | { | 1797 | { |
1798 | struct of_device *op = chip->dev_u.op; | ||
1799 | |||
1798 | if (chip->irq[0]) | 1800 | if (chip->irq[0]) |
1799 | free_irq(chip->irq[0], chip); | 1801 | free_irq(chip->irq[0], chip); |
1800 | 1802 | ||
1801 | if (chip->port) | 1803 | if (chip->port) |
1802 | sbus_iounmap(chip->port, chip->regs_size); | 1804 | of_iounmap(&op->resource[0], chip->port, chip->regs_size); |
1803 | 1805 | ||
1804 | return 0; | 1806 | return 0; |
1805 | } | 1807 | } |
@@ -1816,7 +1818,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = { | |||
1816 | }; | 1818 | }; |
1817 | 1819 | ||
1818 | static int __init snd_cs4231_sbus_create(struct snd_card *card, | 1820 | static int __init snd_cs4231_sbus_create(struct snd_card *card, |
1819 | struct sbus_dev *sdev, | 1821 | struct of_device *op, |
1820 | int dev) | 1822 | int dev) |
1821 | { | 1823 | { |
1822 | struct snd_cs4231 *chip = card->private_data; | 1824 | struct snd_cs4231 *chip = card->private_data; |
@@ -1827,13 +1829,13 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1827 | spin_lock_init(&chip->p_dma.sbus_info.lock); | 1829 | spin_lock_init(&chip->p_dma.sbus_info.lock); |
1828 | mutex_init(&chip->mce_mutex); | 1830 | mutex_init(&chip->mce_mutex); |
1829 | mutex_init(&chip->open_mutex); | 1831 | mutex_init(&chip->open_mutex); |
1830 | chip->dev_u.sdev = sdev; | 1832 | chip->dev_u.op = op; |
1831 | chip->regs_size = sdev->reg_addrs[0].reg_size; | 1833 | chip->regs_size = resource_size(&op->resource[0]); |
1832 | memcpy(&chip->image, &snd_cs4231_original_image, | 1834 | memcpy(&chip->image, &snd_cs4231_original_image, |
1833 | sizeof(snd_cs4231_original_image)); | 1835 | sizeof(snd_cs4231_original_image)); |
1834 | 1836 | ||
1835 | chip->port = sbus_ioremap(&sdev->resource[0], 0, | 1837 | chip->port = of_ioremap(&op->resource[0], 0, |
1836 | chip->regs_size, "cs4231"); | 1838 | chip->regs_size, "cs4231"); |
1837 | if (!chip->port) { | 1839 | if (!chip->port) { |
1838 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); | 1840 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
1839 | return -EIO; | 1841 | return -EIO; |
@@ -1856,14 +1858,14 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1856 | chip->c_dma.address = sbus_dma_addr; | 1858 | chip->c_dma.address = sbus_dma_addr; |
1857 | chip->c_dma.preallocate = sbus_dma_preallocate; | 1859 | chip->c_dma.preallocate = sbus_dma_preallocate; |
1858 | 1860 | ||
1859 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, | 1861 | if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, |
1860 | IRQF_SHARED, "cs4231", chip)) { | 1862 | IRQF_SHARED, "cs4231", chip)) { |
1861 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", | 1863 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", |
1862 | dev, sdev->irqs[0]); | 1864 | dev, op->irqs[0]); |
1863 | snd_cs4231_sbus_free(chip); | 1865 | snd_cs4231_sbus_free(chip); |
1864 | return -EBUSY; | 1866 | return -EBUSY; |
1865 | } | 1867 | } |
1866 | chip->irq[0] = sdev->irqs[0]; | 1868 | chip->irq[0] = op->irqs[0]; |
1867 | 1869 | ||
1868 | if (snd_cs4231_probe(chip) < 0) { | 1870 | if (snd_cs4231_probe(chip) < 0) { |
1869 | snd_cs4231_sbus_free(chip); | 1871 | snd_cs4231_sbus_free(chip); |
@@ -1880,12 +1882,16 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1880 | return 0; | 1882 | return 0; |
1881 | } | 1883 | } |
1882 | 1884 | ||
1883 | static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | 1885 | static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) |
1884 | { | 1886 | { |
1885 | struct resource *rp = &sdev->resource[0]; | 1887 | struct resource *rp = &op->resource[0]; |
1886 | struct snd_card *card; | 1888 | struct snd_card *card; |
1887 | int err; | 1889 | int err; |
1888 | 1890 | ||
1891 | if (strcmp(op->node->parent->name, "sbus") && | ||
1892 | strcmp(op->node->parent->name, "sbi")) | ||
1893 | return -ENODEV; | ||
1894 | |||
1889 | err = cs4231_attach_begin(&card); | 1895 | err = cs4231_attach_begin(&card); |
1890 | if (err) | 1896 | if (err) |
1891 | return err; | 1897 | return err; |
@@ -1894,9 +1900,9 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | |||
1894 | card->shortname, | 1900 | card->shortname, |
1895 | rp->flags & 0xffL, | 1901 | rp->flags & 0xffL, |
1896 | (unsigned long long)rp->start, | 1902 | (unsigned long long)rp->start, |
1897 | sdev->irqs[0]); | 1903 | op->irqs[0]); |
1898 | 1904 | ||
1899 | err = snd_cs4231_sbus_create(card, sdev, dev); | 1905 | err = snd_cs4231_sbus_create(card, op, dev); |
1900 | if (err < 0) { | 1906 | if (err < 0) { |
1901 | snd_card_free(card); | 1907 | snd_card_free(card); |
1902 | return err; | 1908 | return err; |
@@ -2101,12 +2107,25 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) | |||
2101 | } | 2107 | } |
2102 | #endif | 2108 | #endif |
2103 | 2109 | ||
2104 | static int __init cs4231_init(void) | ||
2105 | { | ||
2106 | #ifdef SBUS_SUPPORT | 2110 | #ifdef SBUS_SUPPORT |
2107 | struct sbus_bus *sbus; | 2111 | static struct of_device_id cs4231_match[] = { |
2108 | struct sbus_dev *sdev; | 2112 | { |
2113 | .name = "SUNW,CS4231", | ||
2114 | }, | ||
2115 | {}, | ||
2116 | }; | ||
2117 | |||
2118 | MODULE_DEVICE_TABLE(of, cs4231_match); | ||
2119 | |||
2120 | static struct of_platform_driver cs4231_driver = { | ||
2121 | .name = "audio", | ||
2122 | .match_table = cs4231_match, | ||
2123 | .probe = cs4231_probe, | ||
2124 | }; | ||
2109 | #endif | 2125 | #endif |
2126 | |||
2127 | static int __init cs4231_init(void) | ||
2128 | { | ||
2110 | #ifdef EBUS_SUPPORT | 2129 | #ifdef EBUS_SUPPORT |
2111 | struct linux_ebus *ebus; | 2130 | struct linux_ebus *ebus; |
2112 | struct linux_ebus_device *edev; | 2131 | struct linux_ebus_device *edev; |
@@ -2116,11 +2135,10 @@ static int __init cs4231_init(void) | |||
2116 | found = 0; | 2135 | found = 0; |
2117 | 2136 | ||
2118 | #ifdef SBUS_SUPPORT | 2137 | #ifdef SBUS_SUPPORT |
2119 | for_all_sbusdev(sdev, sbus) { | 2138 | { |
2120 | if (!strcmp(sdev->prom_name, "SUNW,CS4231")) { | 2139 | int err = of_register_driver(&cs4231_driver, &of_bus_type); |
2121 | if (cs4231_sbus_attach(sdev) == 0) | 2140 | if (err) |
2122 | found++; | 2141 | return err; |
2123 | } | ||
2124 | } | 2142 | } |
2125 | #endif | 2143 | #endif |
2126 | #ifdef EBUS_SUPPORT | 2144 | #ifdef EBUS_SUPPORT |
@@ -2147,13 +2165,17 @@ static int __init cs4231_init(void) | |||
2147 | #endif | 2165 | #endif |
2148 | 2166 | ||
2149 | 2167 | ||
2150 | return (found > 0) ? 0 : -EIO; | 2168 | return 0; |
2151 | } | 2169 | } |
2152 | 2170 | ||
2153 | static void __exit cs4231_exit(void) | 2171 | static void __exit cs4231_exit(void) |
2154 | { | 2172 | { |
2155 | struct snd_cs4231 *p = cs4231_list; | 2173 | struct snd_cs4231 *p = cs4231_list; |
2156 | 2174 | ||
2175 | #ifdef SBUS_SUPPORT | ||
2176 | of_unregister_driver(&cs4231_driver); | ||
2177 | #endif | ||
2178 | |||
2157 | while (p != NULL) { | 2179 | while (p != NULL) { |
2158 | struct snd_cs4231 *next = p->next; | 2180 | struct snd_cs4231 *next = p->next; |
2159 | 2181 | ||