Commit afc88ad6 authored by David S. Miller's avatar David S. Miller

cs4231: Convert to EBUS side to pure OF driver.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3ae627a1
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
#define EBUS_SUPPORT #define EBUS_SUPPORT
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/ebus.h>
#include <asm/ebus_dma.h> #include <asm/ebus_dma.h>
#endif #endif
...@@ -71,8 +70,6 @@ struct cs4231_dma_control { ...@@ -71,8 +70,6 @@ struct cs4231_dma_control {
int (*request)(struct cs4231_dma_control *dma_cont, int (*request)(struct cs4231_dma_control *dma_cont,
dma_addr_t bus_addr, size_t len); dma_addr_t bus_addr, size_t len);
unsigned int (*address)(struct cs4231_dma_control *dma_cont); unsigned int (*address)(struct cs4231_dma_control *dma_cont);
void (*preallocate)(struct snd_cs4231 *chip,
struct snd_pcm *pcm);
#ifdef EBUS_SUPPORT #ifdef EBUS_SUPPORT
struct ebus_dma_info ebus_info; struct ebus_dma_info ebus_info;
#endif #endif
...@@ -115,21 +112,12 @@ struct snd_cs4231 { ...@@ -115,21 +112,12 @@ struct snd_cs4231 {
struct mutex mce_mutex; /* mutex for mce register */ struct mutex mce_mutex; /* mutex for mce register */
struct mutex open_mutex; /* mutex for ALSA open/close */ struct mutex open_mutex; /* mutex for ALSA open/close */
union { struct of_device *op;
#ifdef SBUS_SUPPORT
struct of_device *op;
#endif
#ifdef EBUS_SUPPORT
struct pci_dev *pdev;
#endif
} dev_u;
unsigned int irq[2]; unsigned int irq[2];
unsigned int regs_size; unsigned int regs_size;
struct snd_cs4231 *next; struct snd_cs4231 *next;
}; };
static struct snd_cs4231 *cs4231_list;
/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for /* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
* now.... -DaveM * now.... -DaveM
*/ */
...@@ -268,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] = ...@@ -268,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] =
static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
{ {
#ifdef EBUS_SUPPORT
if (cp->flags & CS4231_FLAG_EBUS) if (cp->flags & CS4231_FLAG_EBUS)
return readb(reg_addr); return readb(reg_addr);
else else
#endif
#ifdef SBUS_SUPPORT
return sbus_readb(reg_addr); return sbus_readb(reg_addr);
#endif
} }
static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
void __iomem *reg_addr) void __iomem *reg_addr)
{ {
#ifdef EBUS_SUPPORT
if (cp->flags & CS4231_FLAG_EBUS) if (cp->flags & CS4231_FLAG_EBUS)
return writeb(val, reg_addr); return writeb(val, reg_addr);
else else
#endif
#ifdef SBUS_SUPPORT
return sbus_writeb(val, reg_addr); return sbus_writeb(val, reg_addr);
#endif
} }
/* /*
...@@ -1259,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card) ...@@ -1259,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card)
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
strcpy(pcm->name, "CS4231"); strcpy(pcm->name, "CS4231");
chip->p_dma.preallocate(chip, pcm); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
&chip->op->dev,
64 * 1024, 128 * 1024);
chip->pcm = pcm; chip->pcm = pcm;
...@@ -1627,8 +1609,7 @@ static int __init cs4231_attach_finish(struct snd_card *card) ...@@ -1627,8 +1609,7 @@ static int __init cs4231_attach_finish(struct snd_card *card)
if (err < 0) if (err < 0)
goto out_err; goto out_err;
chip->next = cs4231_list; dev_set_drvdata(&chip->op->dev, chip);
cs4231_list = chip;
dev++; dev++;
return 0; return 0;
...@@ -1783,20 +1764,13 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) ...@@ -1783,20 +1764,13 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
return sbus_readl(base->regs + base->dir + APCVA); return sbus_readl(base->regs + base->dir + APCVA);
} }
static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
{
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
&chip->dev_u.op->dev,
64 * 1024, 128 * 1024);
}
/* /*
* Init and exit routines * Init and exit routines
*/ */
static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
{ {
struct of_device *op = chip->dev_u.op; struct of_device *op = chip->op;
if (chip->irq[0]) if (chip->irq[0])
free_irq(chip->irq[0], chip); free_irq(chip->irq[0], chip);
...@@ -1830,7 +1804,7 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, ...@@ -1830,7 +1804,7 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
spin_lock_init(&chip->p_dma.sbus_info.lock); spin_lock_init(&chip->p_dma.sbus_info.lock);
mutex_init(&chip->mce_mutex); mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex); mutex_init(&chip->open_mutex);
chip->dev_u.op = op; chip->op = op;
chip->regs_size = resource_size(&op->resource[0]); chip->regs_size = resource_size(&op->resource[0]);
memcpy(&chip->image, &snd_cs4231_original_image, memcpy(&chip->image, &snd_cs4231_original_image,
sizeof(snd_cs4231_original_image)); sizeof(snd_cs4231_original_image));
...@@ -1851,13 +1825,11 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, ...@@ -1851,13 +1825,11 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
chip->p_dma.enable = sbus_dma_enable; chip->p_dma.enable = sbus_dma_enable;
chip->p_dma.request = sbus_dma_request; chip->p_dma.request = sbus_dma_request;
chip->p_dma.address = sbus_dma_addr; chip->p_dma.address = sbus_dma_addr;
chip->p_dma.preallocate = sbus_dma_preallocate;
chip->c_dma.prepare = sbus_dma_prepare; chip->c_dma.prepare = sbus_dma_prepare;
chip->c_dma.enable = sbus_dma_enable; chip->c_dma.enable = sbus_dma_enable;
chip->c_dma.request = sbus_dma_request; chip->c_dma.request = sbus_dma_request;
chip->c_dma.address = sbus_dma_addr; chip->c_dma.address = sbus_dma_addr;
chip->c_dma.preallocate = sbus_dma_preallocate;
if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt,
IRQF_SHARED, "cs4231", chip)) { IRQF_SHARED, "cs4231", chip)) {
...@@ -1883,16 +1855,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, ...@@ -1883,16 +1855,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
return 0; return 0;
} }
static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match)
{ {
struct resource *rp = &op->resource[0]; struct resource *rp = &op->resource[0];
struct snd_card *card; struct snd_card *card;
int err; int err;
if (strcmp(op->node->parent->name, "sbus") &&
strcmp(op->node->parent->name, "sbi"))
return -ENODEV;
err = cs4231_attach_begin(&card); err = cs4231_attach_begin(&card);
if (err) if (err)
return err; return err;
...@@ -1956,30 +1924,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont) ...@@ -1956,30 +1924,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
return ebus_dma_addr(&dma_cont->ebus_info); return ebus_dma_addr(&dma_cont->ebus_info);
} }
static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
{
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->dev_u.pdev),
64*1024, 128*1024);
}
/* /*
* Init and exit routines * Init and exit routines
*/ */
static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
{ {
struct of_device *op = chip->op;
if (chip->c_dma.ebus_info.regs) { if (chip->c_dma.ebus_info.regs) {
ebus_dma_unregister(&chip->c_dma.ebus_info); ebus_dma_unregister(&chip->c_dma.ebus_info);
iounmap(chip->c_dma.ebus_info.regs); of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10);
} }
if (chip->p_dma.ebus_info.regs) { if (chip->p_dma.ebus_info.regs) {
ebus_dma_unregister(&chip->p_dma.ebus_info); ebus_dma_unregister(&chip->p_dma.ebus_info);
iounmap(chip->p_dma.ebus_info.regs); of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10);
} }
if (chip->port) if (chip->port)
iounmap(chip->port); of_iounmap(&op->resource[0], chip->port, 0x10);
return 0; return 0;
} }
...@@ -1996,7 +1959,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = { ...@@ -1996,7 +1959,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
}; };
static int __init snd_cs4231_ebus_create(struct snd_card *card, static int __init snd_cs4231_ebus_create(struct snd_card *card,
struct linux_ebus_device *edev, struct of_device *op,
int dev) int dev)
{ {
struct snd_cs4231 *chip = card->private_data; struct snd_cs4231 *chip = card->private_data;
...@@ -2008,35 +1971,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, ...@@ -2008,35 +1971,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
mutex_init(&chip->mce_mutex); mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex); mutex_init(&chip->open_mutex);
chip->flags |= CS4231_FLAG_EBUS; chip->flags |= CS4231_FLAG_EBUS;
chip->dev_u.pdev = edev->bus->self; chip->op = op;
memcpy(&chip->image, &snd_cs4231_original_image, memcpy(&chip->image, &snd_cs4231_original_image,
sizeof(snd_cs4231_original_image)); sizeof(snd_cs4231_original_image));
strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
chip->c_dma.ebus_info.client_cookie = chip; chip->c_dma.ebus_info.client_cookie = chip;
chip->c_dma.ebus_info.irq = edev->irqs[0]; chip->c_dma.ebus_info.irq = op->irqs[0];
strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
chip->p_dma.ebus_info.client_cookie = chip; chip->p_dma.ebus_info.client_cookie = chip;
chip->p_dma.ebus_info.irq = edev->irqs[1]; chip->p_dma.ebus_info.irq = op->irqs[1];
chip->p_dma.prepare = _ebus_dma_prepare; chip->p_dma.prepare = _ebus_dma_prepare;
chip->p_dma.enable = _ebus_dma_enable; chip->p_dma.enable = _ebus_dma_enable;
chip->p_dma.request = _ebus_dma_request; chip->p_dma.request = _ebus_dma_request;
chip->p_dma.address = _ebus_dma_addr; chip->p_dma.address = _ebus_dma_addr;
chip->p_dma.preallocate = _ebus_dma_preallocate;
chip->c_dma.prepare = _ebus_dma_prepare; chip->c_dma.prepare = _ebus_dma_prepare;
chip->c_dma.enable = _ebus_dma_enable; chip->c_dma.enable = _ebus_dma_enable;
chip->c_dma.request = _ebus_dma_request; chip->c_dma.request = _ebus_dma_request;
chip->c_dma.address = _ebus_dma_addr; chip->c_dma.address = _ebus_dma_addr;
chip->c_dma.preallocate = _ebus_dma_preallocate;
chip->port = ioremap(edev->resource[0].start, 0x10); chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231");
chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); chip->p_dma.ebus_info.regs =
chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma");
chip->c_dma.ebus_info.regs =
of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma");
if (!chip->port || !chip->p_dma.ebus_info.regs || if (!chip->port || !chip->p_dma.ebus_info.regs ||
!chip->c_dma.ebus_info.regs) { !chip->c_dma.ebus_info.regs) {
snd_cs4231_ebus_free(chip); snd_cs4231_ebus_free(chip);
...@@ -2084,7 +2047,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, ...@@ -2084,7 +2047,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
return 0; return 0;
} }
static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match)
{ {
struct snd_card *card; struct snd_card *card;
int err; int err;
...@@ -2095,10 +2058,10 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) ...@@ -2095,10 +2058,10 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
sprintf(card->longname, "%s at 0x%lx, irq %d", sprintf(card->longname, "%s at 0x%lx, irq %d",
card->shortname, card->shortname,
edev->resource[0].start, op->resource[0].start,
edev->irqs[0]); op->irqs[0]);
err = snd_cs4231_ebus_create(card, edev, dev); err = snd_cs4231_ebus_create(card, op, dev);
if (err < 0) { if (err < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
...@@ -2108,11 +2071,37 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) ...@@ -2108,11 +2071,37 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
} }
#endif #endif
static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match)
{
#ifdef EBUS_SUPPORT
if (!strcmp(op->node->parent->name, "ebus"))
return cs4231_ebus_probe(op, match);
#endif
#ifdef SBUS_SUPPORT #ifdef SBUS_SUPPORT
if (!strcmp(op->node->parent->name, "sbus") ||
!strcmp(op->node->parent->name, "sbi"))
return cs4231_sbus_probe(op, match);
#endif
return -ENODEV;
}
static int __devexit cs4231_remove(struct of_device *op)
{
struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
snd_card_free(chip->card);
return 0;
}
static struct of_device_id cs4231_match[] = { static struct of_device_id cs4231_match[] = {
{ {
.name = "SUNW,CS4231", .name = "SUNW,CS4231",
}, },
{
.name = "audio",
.compatible = "SUNW,CS4231",
},
{}, {},
}; };
...@@ -2122,70 +2111,17 @@ static struct of_platform_driver cs4231_driver = { ...@@ -2122,70 +2111,17 @@ static struct of_platform_driver cs4231_driver = {
.name = "audio", .name = "audio",
.match_table = cs4231_match, .match_table = cs4231_match,
.probe = cs4231_probe, .probe = cs4231_probe,
.remove = __devexit_p(cs4231_remove),
}; };
#endif
static int __init cs4231_init(void) static int __init cs4231_init(void)
{ {
#ifdef EBUS_SUPPORT return of_register_driver(&cs4231_driver, &of_bus_type);
struct linux_ebus *ebus;
struct linux_ebus_device *edev;
#endif
int found;
found = 0;
#ifdef SBUS_SUPPORT
{
int err = of_register_driver(&cs4231_driver, &of_bus_type);
if (err)
return err;
}
#endif
#ifdef EBUS_SUPPORT
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
int match = 0;
if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
match = 1;
} else if (!strcmp(edev->prom_node->name, "audio")) {
const char *compat;
compat = of_get_property(edev->prom_node,
"compatible", NULL);
if (compat && !strcmp(compat, "SUNW,CS4231"))
match = 1;
}
if (match &&
cs4231_ebus_attach(edev) == 0)
found++;
}
}
#endif
return 0;
} }
static void __exit cs4231_exit(void) static void __exit cs4231_exit(void)
{ {
struct snd_cs4231 *p = cs4231_list;
#ifdef SBUS_SUPPORT
of_unregister_driver(&cs4231_driver); of_unregister_driver(&cs4231_driver);
#endif
while (p != NULL) {
struct snd_cs4231 *next = p->next;
snd_card_free(p->card);
p = next;
}
cs4231_list = NULL;
} }
module_init(cs4231_init); module_init(cs4231_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment