X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fsparc%2Famd7930.c;h=c899786f30f5fb5584595889123f954e9045b51d;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=bd8a850e93eaaa85bd97dd1c14e84b4289efb026;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index bd8a850e9..c899786f3 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -46,6 +46,7 @@ #include #include #include +#include static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -311,7 +312,7 @@ struct amd7930_map { #define AMR_PP_PPCR2 0xC8 #define AMR_PP_PPCR3 0xC9 -typedef struct snd_amd7930 { +struct snd_amd7930 { spinlock_t lock; void __iomem *regs; u32 flags; @@ -320,10 +321,10 @@ typedef struct snd_amd7930 { struct amd7930_map map; - snd_card_t *card; - snd_pcm_t *pcm; - snd_pcm_substream_t *playback_substream; - snd_pcm_substream_t *capture_substream; + struct snd_card *card; + struct snd_pcm *pcm; + struct snd_pcm_substream *playback_substream; + struct snd_pcm_substream *capture_substream; /* Playback/Capture buffer state. */ unsigned char *p_orig, *p_cur; @@ -335,16 +336,15 @@ typedef struct snd_amd7930 { int pgain; int mgain; - struct sbus_dev *sdev; unsigned int irq; unsigned int regs_size; struct snd_amd7930 *next; -} amd7930_t; +}; -static amd7930_t *amd7930_list; +static struct snd_amd7930 *amd7930_list; /* Idle the AMD7930 chip. The amd->lock is not held. */ -static __inline__ void amd7930_idle(amd7930_t *amd) +static __inline__ void amd7930_idle(struct snd_amd7930 *amd) { unsigned long flags; @@ -355,7 +355,7 @@ static __inline__ void amd7930_idle(amd7930_t *amd) } /* Enable chip interrupts. The amd->lock is not held. */ -static __inline__ void amd7930_enable_ints(amd7930_t *amd) +static __inline__ void amd7930_enable_ints(struct snd_amd7930 *amd) { unsigned long flags; @@ -366,7 +366,7 @@ static __inline__ void amd7930_enable_ints(amd7930_t *amd) } /* Disable chip interrupts. The amd->lock is not held. */ -static __inline__ void amd7930_disable_ints(amd7930_t *amd) +static __inline__ void amd7930_disable_ints(struct snd_amd7930 *amd) { unsigned long flags; @@ -379,7 +379,7 @@ static __inline__ void amd7930_disable_ints(amd7930_t *amd) /* Commit amd7930_map settings to the hardware. * The amd->lock is held and local interrupts are disabled. */ -static void __amd7930_write_map(amd7930_t *amd) +static void __amd7930_write_map(struct snd_amd7930 *amd) { struct amd7930_map *map = &amd->map; @@ -473,7 +473,7 @@ static __const__ __u16 ger_coeff[] = { /* Update amd7930_map settings and program them into the hardware. * The amd->lock is held and local interrupts are disabled. */ -static void __amd7930_update_map(amd7930_t *amd) +static void __amd7930_update_map(struct snd_amd7930 *amd) { struct amd7930_map *map = &amd->map; int level; @@ -491,9 +491,9 @@ static void __amd7930_update_map(amd7930_t *amd) __amd7930_write_map(amd); } -static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id) { - amd7930_t *amd = dev_id; + struct snd_amd7930 *amd = dev_id; unsigned int elapsed; u8 ir; @@ -534,7 +534,7 @@ static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id, struct pt_regs * return IRQ_HANDLED; } -static int snd_amd7930_trigger(amd7930_t *amd, unsigned int flag, int cmd) +static int snd_amd7930_trigger(struct snd_amd7930 *amd, unsigned int flag, int cmd) { unsigned long flags; int result = 0; @@ -564,24 +564,24 @@ static int snd_amd7930_trigger(amd7930_t *amd, unsigned int flag, int cmd) return result; } -static int snd_amd7930_playback_trigger(snd_pcm_substream_t * substream, +static int snd_amd7930_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); return snd_amd7930_trigger(amd, AMD7930_FLAG_PLAYBACK, cmd); } -static int snd_amd7930_capture_trigger(snd_pcm_substream_t * substream, +static int snd_amd7930_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); return snd_amd7930_trigger(amd, AMD7930_FLAG_CAPTURE, cmd); } -static int snd_amd7930_playback_prepare(snd_pcm_substream_t * substream) +static int snd_amd7930_playback_prepare(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned long flags; u8 new_mmr1; @@ -610,10 +610,10 @@ static int snd_amd7930_playback_prepare(snd_pcm_substream_t * substream) return 0; } -static int snd_amd7930_capture_prepare(snd_pcm_substream_t * substream) +static int snd_amd7930_capture_prepare(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned long flags; u8 new_mmr1; @@ -642,9 +642,9 @@ static int snd_amd7930_capture_prepare(snd_pcm_substream_t * substream) return 0; } -static snd_pcm_uframes_t snd_amd7930_playback_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_amd7930_playback_pointer(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); size_t ptr; if (!(amd->flags & AMD7930_FLAG_PLAYBACK)) @@ -653,9 +653,9 @@ static snd_pcm_uframes_t snd_amd7930_playback_pointer(snd_pcm_substream_t * subs return bytes_to_frames(substream->runtime, ptr); } -static snd_pcm_uframes_t snd_amd7930_capture_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_amd7930_capture_pointer(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); size_t ptr; if (!(amd->flags & AMD7930_FLAG_CAPTURE)) @@ -666,7 +666,7 @@ static snd_pcm_uframes_t snd_amd7930_capture_pointer(snd_pcm_substream_t * subst } /* Playback and capture have identical properties. */ -static snd_pcm_hardware_t snd_amd7930_pcm_hw = +static struct snd_pcm_hardware snd_amd7930_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -686,54 +686,54 @@ static snd_pcm_hardware_t snd_amd7930_pcm_hw = .periods_max = 1024, }; -static int snd_amd7930_playback_open(snd_pcm_substream_t * substream) +static int snd_amd7930_playback_open(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; amd->playback_substream = substream; runtime->hw = snd_amd7930_pcm_hw; return 0; } -static int snd_amd7930_capture_open(snd_pcm_substream_t * substream) +static int snd_amd7930_capture_open(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; amd->capture_substream = substream; runtime->hw = snd_amd7930_pcm_hw; return 0; } -static int snd_amd7930_playback_close(snd_pcm_substream_t * substream) +static int snd_amd7930_playback_close(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); amd->playback_substream = NULL; return 0; } -static int snd_amd7930_capture_close(snd_pcm_substream_t * substream) +static int snd_amd7930_capture_close(struct snd_pcm_substream *substream) { - amd7930_t *amd = snd_pcm_substream_chip(substream); + struct snd_amd7930 *amd = snd_pcm_substream_chip(substream); amd->capture_substream = NULL; return 0; } -static int snd_amd7930_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) +static int snd_amd7930_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } -static int snd_amd7930_hw_free(snd_pcm_substream_t * substream) +static int snd_amd7930_hw_free(struct snd_pcm_substream *substream) { return snd_pcm_lib_free_pages(substream); } -static snd_pcm_ops_t snd_amd7930_playback_ops = { +static struct snd_pcm_ops snd_amd7930_playback_ops = { .open = snd_amd7930_playback_open, .close = snd_amd7930_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -744,7 +744,7 @@ static snd_pcm_ops_t snd_amd7930_playback_ops = { .pointer = snd_amd7930_playback_pointer, }; -static snd_pcm_ops_t snd_amd7930_capture_ops = { +static struct snd_pcm_ops snd_amd7930_capture_ops = { .open = snd_amd7930_capture_open, .close = snd_amd7930_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -755,17 +755,9 @@ static snd_pcm_ops_t snd_amd7930_capture_ops = { .pointer = snd_amd7930_capture_pointer, }; -static void snd_amd7930_pcm_free(snd_pcm_t *pcm) -{ - amd7930_t *amd = pcm->private_data; - - amd->pcm = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -static int __init snd_amd7930_pcm(amd7930_t *amd) +static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd) { - snd_pcm_t *pcm; + struct snd_pcm *pcm; int err; if ((err = snd_pcm_new(amd->card, @@ -780,7 +772,6 @@ static int __init snd_amd7930_pcm(amd7930_t *amd) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops); pcm->private_data = amd; - pcm->private_free = snd_amd7930_pcm_free; pcm->info_flags = 0; strcpy(pcm->name, amd->card->shortname); amd->pcm = pcm; @@ -796,7 +787,7 @@ static int __init snd_amd7930_pcm(amd7930_t *amd) #define VOLUME_CAPTURE 1 #define VOLUME_PLAYBACK 2 -static int snd_amd7930_info_volume(snd_kcontrol_t *kctl, snd_ctl_elem_info_t *uinfo) +static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { int type = kctl->private_value; @@ -813,9 +804,9 @@ static int snd_amd7930_info_volume(snd_kcontrol_t *kctl, snd_ctl_elem_info_t *ui return 0; } -static int snd_amd7930_get_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *ucontrol) +static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { - amd7930_t *amd = snd_kcontrol_chip(kctl); + struct snd_amd7930 *amd = snd_kcontrol_chip(kctl); int type = kctl->private_value; int *swval; @@ -841,9 +832,9 @@ static int snd_amd7930_get_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *uc return 0; } -static int snd_amd7930_put_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *ucontrol) +static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { - amd7930_t *amd = snd_kcontrol_chip(kctl); + struct snd_amd7930 *amd = snd_kcontrol_chip(kctl); unsigned long flags; int type = kctl->private_value; int *swval, change; @@ -879,7 +870,7 @@ static int snd_amd7930_put_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *uc return change; } -static snd_kcontrol_new_t amd7930_controls[] __initdata = { +static struct snd_kcontrol_new amd7930_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Monitor Volume", @@ -909,9 +900,9 @@ static snd_kcontrol_new_t amd7930_controls[] __initdata = { }, }; -static int __init snd_amd7930_mixer(amd7930_t *amd) +static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd) { - snd_card_t *card; + struct snd_card *card; int idx, err; snd_assert(amd != NULL && amd->card != NULL, return -EINVAL); @@ -928,7 +919,7 @@ static int __init snd_amd7930_mixer(amd7930_t *amd) return 0; } -static int snd_amd7930_free(amd7930_t *amd) +static int snd_amd7930_free(struct snd_amd7930 *amd) { amd7930_idle(amd); @@ -943,37 +934,34 @@ static int snd_amd7930_free(amd7930_t *amd) return 0; } -static int snd_amd7930_dev_free(snd_device_t *device) +static int snd_amd7930_dev_free(struct snd_device *device) { - amd7930_t *amd = device->device_data; + struct snd_amd7930 *amd = device->device_data; return snd_amd7930_free(amd); } -static snd_device_ops_t snd_amd7930_dev_ops = { +static struct snd_device_ops snd_amd7930_dev_ops = { .dev_free = snd_amd7930_dev_free, }; -static int __init snd_amd7930_create(snd_card_t *card, - struct sbus_dev *sdev, - struct resource *rp, - unsigned int reg_size, - struct linux_prom_irqs *irq_prop, - int dev, - amd7930_t **ramd) +static int __devinit snd_amd7930_create(struct snd_card *card, + struct resource *rp, + unsigned int reg_size, + int irq, int dev, + struct snd_amd7930 **ramd) { unsigned long flags; - amd7930_t *amd; + struct snd_amd7930 *amd; int err; *ramd = NULL; - amd = kcalloc(1, sizeof(*amd), GFP_KERNEL); + amd = kzalloc(sizeof(*amd), GFP_KERNEL); if (amd == NULL) return -ENOMEM; spin_lock_init(&amd->lock); amd->card = card; - amd->sdev = sdev; amd->regs_size = reg_size; amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); @@ -984,15 +972,14 @@ static int __init snd_amd7930_create(snd_card_t *card, amd7930_idle(amd); - if (request_irq(irq_prop->pri, snd_amd7930_interrupt, - SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) { - snd_printk("amd7930-%d: Unable to grab IRQ %s\n", - dev, - __irq_itoa(irq_prop->pri)); + if (request_irq(irq, snd_amd7930_interrupt, + IRQF_DISABLED | IRQF_SHARED, "amd7930", amd)) { + snd_printk("amd7930-%d: Unable to grab IRQ %d\n", + dev, irq); snd_amd7930_free(amd); return -EBUSY; } - amd->irq = irq_prop->pri; + amd->irq = irq; amd7930_enable_ints(amd); @@ -1026,60 +1013,35 @@ static int __init snd_amd7930_create(snd_card_t *card, return 0; } -static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) +static int __devinit amd7930_attach_common(struct resource *rp, int irq) { - static int dev; - struct linux_prom_registers reg_prop; - struct linux_prom_irqs irq_prop; - struct resource res, *rp; - snd_card_t *card; - amd7930_t *amd; + static int dev_num; + struct snd_card *card; + struct snd_amd7930 *amd; int err; - if (dev >= SNDRV_CARDS) + if (dev_num >= SNDRV_CARDS) return -ENODEV; - if (!enable[dev]) { - dev++; + if (!enable[dev_num]) { + dev_num++; return -ENOENT; } - err = prom_getproperty(prom_node, "intr", - (char *) &irq_prop, sizeof(irq_prop)); - if (err < 0) { - snd_printk("amd7930-%d: Firmware node lacks IRQ property.\n", dev); - return -ENODEV; - } - - err = prom_getproperty(prom_node, "reg", - (char *) ®_prop, sizeof(reg_prop)); - if (err < 0) { - snd_printk("amd7930-%d: Firmware node lacks register property.\n", dev); - return -ENODEV; - } - - if (sdev) { - rp = &sdev->resource[0]; - } else { - rp = &res; - rp->start = reg_prop.phys_addr; - rp->end = rp->start + reg_prop.reg_size - 1; - rp->flags = IORESOURCE_IO | (reg_prop.which_io & 0xff); - } - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; strcpy(card->driver, "AMD7930"); strcpy(card->shortname, "Sun AMD7930"); - sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %s", + sprintf(card->longname, "%s at 0x%02lx:0x%08Lx, irq %d", card->shortname, rp->flags & 0xffL, - rp->start, - __irq_itoa(irq_prop.pri)); + (unsigned long long)rp->start, + irq); - if ((err = snd_amd7930_create(card, sdev, rp, reg_prop.reg_size, - &irq_prop, dev, &amd)) < 0) + if ((err = snd_amd7930_create(card, rp, + (rp->end - rp->start) + 1, + irq, dev_num, &amd)) < 0) goto out_err; if ((err = snd_amd7930_pcm(amd)) < 0) @@ -1094,7 +1056,8 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) amd->next = amd7930_list; amd7930_list = amd; - dev++; + dev_num++; + return 0; out_err: @@ -1102,37 +1065,79 @@ out_err: return err; } -static int __init amd7930_init(void) +static int __devinit amd7930_obio_attach(struct device_node *dp) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; - int node, found; + struct linux_prom_registers *regs; + struct linux_prom_irqs *irqp; + struct resource res, *rp; + int len; - found = 0; + irqp = of_get_property(dp, "intr", &len); + if (!irqp) { + snd_printk("%s: Firmware node lacks IRQ property.\n", + dp->full_name); + return -ENODEV; + } + + regs = of_get_property(dp, "reg", &len); + if (!regs) { + snd_printk("%s: Firmware node lacks register property.\n", + dp->full_name); + return -ENODEV; + } + + rp = &res; + rp->start = regs->phys_addr; + rp->end = rp->start + regs->reg_size - 1; + rp->flags = IORESOURCE_IO | (regs->which_io & 0xff); + + return amd7930_attach_common(rp, irqp->pri); +} + +static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match) +{ + struct sbus_dev *sdev = to_sbus_device(&dev->dev); + + return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]); +} + +static struct of_device_id amd7930_match[] = { + { + .name = "audio", + }, + {}, +}; + +static struct of_platform_driver amd7930_sbus_driver = { + .name = "audio", + .match_table = amd7930_match, + .probe = amd7930_sbus_probe, +}; + +static int __init amd7930_init(void) +{ + struct device_node *dp; /* Try to find the sun4c "audio" node first. */ - node = prom_getchild(prom_root_node); - node = prom_searchsiblings(node, "audio"); - if (node && amd7930_attach(node, NULL) == 0) - found++; + dp = of_find_node_by_path("/"); + dp = dp->child; + while (dp) { + if (!strcmp(dp->name, "audio")) + amd7930_obio_attach(dp); - /* Probe each SBUS for amd7930 chips. */ - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "audio")) { - if (amd7930_attach(sdev->prom_node, sdev) == 0) - found++; - } + dp = dp->sibling; } - return (found > 0) ? 0 : -EIO; + /* Probe each SBUS for amd7930 chips. */ + return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type); } static void __exit amd7930_exit(void) { - amd7930_t *p = amd7930_list; + struct snd_amd7930 *p = amd7930_list; while (p != NULL) { - amd7930_t *next = p->next; + struct snd_amd7930 *next = p->next; snd_card_free(p->card); @@ -1140,6 +1145,8 @@ static void __exit amd7930_exit(void) } amd7930_list = NULL; + + of_unregister_driver(&amd7930_sbus_driver); } module_init(amd7930_init);