aboutsummaryrefslogtreecommitdiffstats
path: root/sound/sparc
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-09-05 09:05:08 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:59:57 -0400
commitafeacfd5f7ee76fe90f95039170f70e3699a6b94 (patch)
tree3d1488232c1c461e2c1b1b6f7c28767c7b96eda8 /sound/sparc
parentf545714ece023b8cf10b41d56b9fdac605797aff (diff)
[ALSA] dbri: conversion to OpenFirmware framework
This patch converts the dbri driver to use OF framework. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/sparc')
-rw-r--r--sound/sparc/dbri.c143
1 files changed, 69 insertions, 74 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 12d11fc5f825..e96023fcdbec 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -66,6 +66,7 @@
66#include <sound/control.h> 66#include <sound/control.h>
67#include <sound/initval.h> 67#include <sound/initval.h>
68 68
69#include <asm/prom.h>
69#include <asm/sbus.h> 70#include <asm/sbus.h>
70#include <asm/atomic.h> 71#include <asm/atomic.h>
71 72
@@ -296,8 +297,6 @@ struct dbri_streaminfo {
296 297
297/* This structure holds the information for both chips (DBRI & CS4215) */ 298/* This structure holds the information for both chips (DBRI & CS4215) */
298struct snd_dbri { 299struct snd_dbri {
299 struct snd_card *card; /* ALSA card */
300
301 int regs_size, irq; /* Needed for unload */ 300 int regs_size, irq; /* Needed for unload */
302 struct sbus_dev *sdev; /* SBUS device info */ 301 struct sbus_dev *sdev; /* SBUS device info */
303 spinlock_t lock; 302 spinlock_t lock;
@@ -318,8 +317,6 @@ struct snd_dbri {
318 struct cs4215 mm; /* mmcodec special info */ 317 struct cs4215 mm; /* mmcodec special info */
319 /* per stream (playback/record) info */ 318 /* per stream (playback/record) info */
320 struct dbri_streaminfo stream_info[DBRI_NO_STREAMS]; 319 struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
321
322 struct snd_dbri *next;
323}; 320};
324 321
325#define DBRI_MAX_VOLUME 63 /* Output volume */ 322#define DBRI_MAX_VOLUME 63 /* Output volume */
@@ -571,8 +568,6 @@ struct snd_dbri {
571#define DBRI_STREAM(dbri, substream) \ 568#define DBRI_STREAM(dbri, substream) \
572 &dbri->stream_info[DBRI_STREAMNO(substream)] 569 &dbri->stream_info[DBRI_STREAMNO(substream)]
573 570
574static struct snd_dbri *dbri_list; /* All DBRI devices */
575
576/* 571/*
577 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. 572 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
578 * So we have to reverse the bits. Note: not all bit lengths are supported 573 * So we have to reverse the bits. Note: not all bit lengths are supported
@@ -748,7 +743,7 @@ static void dbri_reset(struct snd_dbri *dbri)
748} 743}
749 744
750/* Lock must not be held before calling this */ 745/* Lock must not be held before calling this */
751static void __init dbri_initialize(struct snd_dbri *dbri) 746static void __devinit dbri_initialize(struct snd_dbri *dbri)
752{ 747{
753 s32 *cmd; 748 s32 *cmd;
754 u32 dma_addr; 749 u32 dma_addr;
@@ -1308,7 +1303,7 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins.
1308 * Lock must not be held before calling it. 1303 * Lock must not be held before calling it.
1309 1304
1310*/ 1305*/
1311static __init void cs4215_setup_pipes(struct snd_dbri *dbri) 1306static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
1312{ 1307{
1313 unsigned long flags; 1308 unsigned long flags;
1314 1309
@@ -1341,7 +1336,7 @@ static __init void cs4215_setup_pipes(struct snd_dbri *dbri)
1341 dbri_cmdwait(dbri); 1336 dbri_cmdwait(dbri);
1342} 1337}
1343 1338
1344static __init int cs4215_init_data(struct cs4215 *mm) 1339static __devinit int cs4215_init_data(struct cs4215 *mm)
1345{ 1340{
1346 /* 1341 /*
1347 * No action, memory resetting only. 1342 * No action, memory resetting only.
@@ -1633,7 +1628,7 @@ static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
1633/* 1628/*
1634 * 1629 *
1635 */ 1630 */
1636static __init int cs4215_init(struct snd_dbri *dbri) 1631static __devinit int cs4215_init(struct snd_dbri *dbri)
1637{ 1632{
1638 u32 reg2 = sbus_readl(dbri->regs + REG2); 1633 u32 reg2 = sbus_readl(dbri->regs + REG2);
1639 dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); 1634 dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
@@ -2218,12 +2213,12 @@ static struct snd_pcm_ops snd_dbri_ops = {
2218 .pointer = snd_dbri_pointer, 2213 .pointer = snd_dbri_pointer,
2219}; 2214};
2220 2215
2221static int __devinit snd_dbri_pcm(struct snd_dbri *dbri) 2216static int __devinit snd_dbri_pcm(struct snd_card *card)
2222{ 2217{
2223 struct snd_pcm *pcm; 2218 struct snd_pcm *pcm;
2224 int err; 2219 int err;
2225 2220
2226 if ((err = snd_pcm_new(dbri->card, 2221 if ((err = snd_pcm_new(card,
2227 /* ID */ "sun_dbri", 2222 /* ID */ "sun_dbri",
2228 /* device */ 0, 2223 /* device */ 0,
2229 /* playback count */ 1, 2224 /* playback count */ 1,
@@ -2234,9 +2229,9 @@ static int __devinit snd_dbri_pcm(struct snd_dbri *dbri)
2234 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); 2229 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
2235 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); 2230 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
2236 2231
2237 pcm->private_data = dbri; 2232 pcm->private_data = card->private_data;
2238 pcm->info_flags = 0; 2233 pcm->info_flags = 0;
2239 strcpy(pcm->name, dbri->card->shortname); 2234 strcpy(pcm->name, card->shortname);
2240 2235
2241 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, 2236 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
2242 SNDRV_DMA_TYPE_CONTINUOUS, 2237 SNDRV_DMA_TYPE_CONTINUOUS,
@@ -2422,14 +2417,14 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
2422 CS4215_SINGLE("Mic boost", 4, 4, 1, 1) 2417 CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
2423}; 2418};
2424 2419
2425static int __init snd_dbri_mixer(struct snd_dbri *dbri) 2420static int __devinit snd_dbri_mixer(struct snd_card *card)
2426{ 2421{
2427 struct snd_card *card;
2428 int idx, err; 2422 int idx, err;
2423 struct snd_dbri *dbri;
2429 2424
2430 snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL); 2425 snd_assert(card != NULL && card->private_data != NULL, return -EINVAL);
2426 dbri = card->private_data;
2431 2427
2432 card = dbri->card;
2433 strcpy(card->mixername, card->shortname); 2428 strcpy(card->mixername, card->shortname);
2434 2429
2435 for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) { 2430 for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
@@ -2485,15 +2480,16 @@ static void dbri_debug_read(struct snd_info_entry *entry,
2485} 2480}
2486#endif 2481#endif
2487 2482
2488void snd_dbri_proc(struct snd_dbri *dbri) 2483void __devinit snd_dbri_proc(struct snd_card *card)
2489{ 2484{
2485 struct snd_dbri *dbri = card->private_data;
2490 struct snd_info_entry *entry; 2486 struct snd_info_entry *entry;
2491 2487
2492 if (!snd_card_proc_new(dbri->card, "regs", &entry)) 2488 if (!snd_card_proc_new(card, "regs", &entry))
2493 snd_info_set_text_ops(entry, dbri, dbri_regs_read); 2489 snd_info_set_text_ops(entry, dbri, dbri_regs_read);
2494 2490
2495#ifdef DBRI_DEBUG 2491#ifdef DBRI_DEBUG
2496 if (!snd_card_proc_new(dbri->card, "debug", &entry)) { 2492 if (!snd_card_proc_new(card, "debug", &entry)) {
2497 snd_info_set_text_ops(entry, dbri, dbri_debug_read); 2493 snd_info_set_text_ops(entry, dbri, dbri_debug_read);
2498 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ 2494 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
2499 } 2495 }
@@ -2507,17 +2503,16 @@ void snd_dbri_proc(struct snd_dbri *dbri)
2507*/ 2503*/
2508static void snd_dbri_free(struct snd_dbri *dbri); 2504static void snd_dbri_free(struct snd_dbri *dbri);
2509 2505
2510static int __init snd_dbri_create(struct snd_card *card, 2506static int __devinit snd_dbri_create(struct snd_card *card,
2511 struct sbus_dev *sdev, 2507 struct sbus_dev *sdev,
2512 struct linux_prom_irqs *irq, int dev) 2508 int irq, int dev)
2513{ 2509{
2514 struct snd_dbri *dbri = card->private_data; 2510 struct snd_dbri *dbri = card->private_data;
2515 int err; 2511 int err;
2516 2512
2517 spin_lock_init(&dbri->lock); 2513 spin_lock_init(&dbri->lock);
2518 dbri->card = card;
2519 dbri->sdev = sdev; 2514 dbri->sdev = sdev;
2520 dbri->irq = irq->pri; 2515 dbri->irq = irq;
2521 2516
2522 dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), 2517 dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma),
2523 &dbri->dma_dvma); 2518 &dbri->dma_dvma);
@@ -2555,9 +2550,6 @@ static int __init snd_dbri_create(struct snd_card *card,
2555 return err; 2550 return err;
2556 } 2551 }
2557 2552
2558 dbri->next = dbri_list;
2559 dbri_list = dbri;
2560
2561 return 0; 2553 return 0;
2562} 2554}
2563 2555
@@ -2577,20 +2569,19 @@ static void snd_dbri_free(struct snd_dbri *dbri)
2577 (void *)dbri->dma, dbri->dma_dvma); 2569 (void *)dbri->dma, dbri->dma_dvma);
2578} 2570}
2579 2571
2580static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) 2572static int __devinit dbri_probe(struct of_device *of_dev,
2573 const struct of_device_id *match)
2581{ 2574{
2575 struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
2582 struct snd_dbri *dbri; 2576 struct snd_dbri *dbri;
2583 struct linux_prom_irqs irq; 2577 int irq;
2584 struct resource *rp; 2578 struct resource *rp;
2585 struct snd_card *card; 2579 struct snd_card *card;
2586 static int dev = 0; 2580 static int dev = 0;
2587 int err; 2581 int err;
2588 2582
2589 if (sdev->prom_name[9] < 'e') { 2583 dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
2590 printk(KERN_ERR "DBRI: unsupported chip version %c found.\n", 2584 sdev->prom_name, sdev->slot);
2591 sdev->prom_name[9]);
2592 return -EIO;
2593 }
2594 2585
2595 if (dev >= SNDRV_CARDS) 2586 if (dev >= SNDRV_CARDS)
2596 return -ENODEV; 2587 return -ENODEV;
@@ -2599,10 +2590,9 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
2599 return -ENOENT; 2590 return -ENOENT;
2600 } 2591 }
2601 2592
2602 err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); 2593 irq = sdev->irqs[0];
2603 if (err < 0) { 2594 if (irq <= 0) {
2604 printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", 2595 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
2605 dev);
2606 return -ENODEV; 2596 return -ENODEV;
2607 } 2597 }
2608 2598
@@ -2616,24 +2606,26 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
2616 rp = &sdev->resource[0]; 2606 rp = &sdev->resource[0];
2617 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", 2607 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
2618 card->shortname, 2608 card->shortname,
2619 rp->flags & 0xffL, (unsigned long long)rp->start, irq.pri); 2609 rp->flags & 0xffL, (unsigned long long)rp->start, irq);
2620 2610
2621 if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { 2611 err = snd_dbri_create(card, sdev, irq, dev);
2612 if (err < 0) {
2622 snd_card_free(card); 2613 snd_card_free(card);
2623 return err; 2614 return err;
2624 } 2615 }
2625 2616
2626 dbri = card->private_data; 2617 dbri = card->private_data;
2627 err = snd_dbri_pcm(dbri); 2618 err = snd_dbri_pcm(card);
2628 if (err < 0) 2619 if (err < 0)
2629 goto _err; 2620 goto _err;
2630 2621
2631 err = snd_dbri_mixer(dbri); 2622 err = snd_dbri_mixer(card);
2632 if (err < 0) 2623 if (err < 0)
2633 goto _err; 2624 goto _err;
2634 2625
2635 /* /proc file handling */ 2626 /* /proc file handling */
2636 snd_dbri_proc(dbri); 2627 snd_dbri_proc(card);
2628 dev_set_drvdata(&of_dev->dev, card);
2637 2629
2638 err = snd_card_register(card); 2630 err = snd_card_register(card);
2639 if (err < 0) 2631 if (err < 0)
@@ -2652,43 +2644,46 @@ _err:
2652 return err; 2644 return err;
2653} 2645}
2654 2646
2655/* Probe for the dbri chip and then attach the driver. */ 2647static int __devexit dbri_remove(struct of_device *dev)
2656static int __init dbri_init(void)
2657{ 2648{
2658 struct sbus_bus *sbus; 2649 struct snd_card *card = dev_get_drvdata(&dev->dev);
2659 struct sbus_dev *sdev;
2660 int found = 0;
2661
2662 /* Probe each SBUS for the DBRI chip(s). */
2663 for_all_sbusdev(sdev, sbus) {
2664 /*
2665 * The version is coded in the last character
2666 */
2667 if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) {
2668 dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
2669 sdev->prom_name, sdev->slot);
2670 2650
2671 if (dbri_attach(sdev->prom_node, sdev) == 0) 2651 snd_dbri_free(card->private_data);
2672 found++; 2652 snd_card_free(card);
2673 }
2674 }
2675 2653
2676 return (found > 0) ? 0 : -EIO; 2654 dev_set_drvdata(&dev->dev, NULL);
2655
2656 return 0;
2677} 2657}
2678 2658
2679static void __exit dbri_exit(void) 2659static struct of_device_id dbri_match[] = {
2680{ 2660 {
2681 struct snd_dbri *this = dbri_list; 2661 .name = "SUNW,DBRIe",
2662 },
2663 {
2664 .name = "SUNW,DBRIf",
2665 },
2666 {},
2667};
2682 2668
2683 while (this != NULL) { 2669MODULE_DEVICE_TABLE(of, dbri_match);
2684 struct snd_dbri *next = this->next;
2685 struct snd_card *card = this->card;
2686 2670
2687 snd_dbri_free(this); 2671static struct of_platform_driver dbri_sbus_driver = {
2688 snd_card_free(card); 2672 .name = "dbri",
2689 this = next; 2673 .match_table = dbri_match,
2690 } 2674 .probe = dbri_probe,
2691 dbri_list = NULL; 2675 .remove = __devexit_p(dbri_remove),
2676};
2677
2678/* Probe for the dbri chip and then attach the driver. */
2679static int __init dbri_init(void)
2680{
2681 return of_register_driver(&dbri_sbus_driver, &sbus_bus_type);
2682}
2683
2684static void __exit dbri_exit(void)
2685{
2686 of_unregister_driver(&dbri_sbus_driver);
2692} 2687}
2693 2688
2694module_init(dbri_init); 2689module_init(dbri_init);