X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Fdmasound%2Fdmasound_awacs.c;h=c8e210326893b3f64940c570f95fb21bc8790cbb;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=7b5049166afe79679094e112c1472cdcab1f20e9;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c index 7b5049166..c8e210326 100644 --- a/sound/oss/dmasound/dmasound_awacs.c +++ b/sound/oss/dmasound/dmasound_awacs.c @@ -1,10 +1,10 @@ /* - * linux/drivers/sound/dmasound/dmasound_awacs.c + * linux/sound/oss/dmasound/dmasound_awacs.c * * PowerMac `AWACS' and `Burgundy' DMA Sound Driver * with some limited support for DACA & Tumbler * - * See linux/drivers/sound/dmasound/dmasound_core.c for copyright and + * See linux/sound/oss/dmasound/dmasound_core.c for copyright and * history prior to 2001/01/26. * * 26/01/2001 ed 0.1 Iain Sandoe @@ -76,12 +76,11 @@ #include #include #include -#include #include #include #include #include -#include +#include #ifdef CONFIG_ADB_CUDA #include #endif @@ -89,8 +88,6 @@ #include #endif -#include - #include #include #include @@ -119,18 +116,19 @@ * Interrupt numbers and addresses, & info obtained from the device tree. */ static int awacs_irq, awacs_tx_irq, awacs_rx_irq; -static volatile struct awacs_regs *awacs; -static volatile u32 *i2s; -static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma; +static volatile struct awacs_regs __iomem *awacs; +static volatile u32 __iomem *i2s; +static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma; static int awacs_rate_index; static int awacs_subframe; static struct device_node* awacs_node; static struct device_node* i2s_node; +static struct resource awacs_rsrc[3]; static char awacs_name[64]; static int awacs_revision; static int awacs_sleeping; -static DECLARE_MUTEX(dmasound_sem); +static DEFINE_MUTEX(dmasound_mutex); static int sound_device_id; /* exists after iMac revA */ static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */ @@ -147,8 +145,8 @@ static int has_ziva; /* for earlier powerbooks which need fiddling with mac-io to enable * cd etc. */ -static unsigned char *latch_base; -static unsigned char *macio_base; +static unsigned char __iomem *latch_base; +static unsigned char __iomem *macio_base; /* * Space for the DBDMA command blocks. @@ -256,7 +254,7 @@ static int awacs_burgundy_read_mvolume(unsigned address); static volatile struct dbdma_cmd *emergency_dbdma_cmd; -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM /* * Stuff for restoring after a sleep. */ @@ -264,7 +262,7 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when); struct pmu_sleep_notifier awacs_sleep_notifier = { awacs_sleep_notify, SLEEP_LEVEL_SOUND, }; -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* for (soft) sample rate translations */ int expand_bal; /* Balance factor for expanding (not volume!) */ @@ -272,7 +270,7 @@ int expand_read_bal; /* Balance factor for expanding reads (not volume!) */ /*** Low level stuff *********************************************************/ -static void *PMacAlloc(unsigned int size, int flags); +static void *PMacAlloc(unsigned int size, gfp_t flags); static void PMacFree(void *ptr, unsigned int size); static int PMacIrqInit(void); #ifdef MODULE @@ -312,11 +310,11 @@ extern int daca_enter_sleep(void); extern int daca_leave_sleep(void); #define TRY_LOCK() \ - if ((rc = down_interruptible(&dmasound_sem)) != 0) \ + if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \ return rc; -#define LOCK() down(&dmasound_sem); +#define LOCK() mutex_lock(&dmasound_mutex); -#define UNLOCK() up(&dmasound_sem); +#define UNLOCK() mutex_unlock(&dmasound_mutex); /* We use different versions that the ones provided in dmasound.h * @@ -326,12 +324,12 @@ extern int daca_leave_sleep(void); #undef IOCTL_OUT #define IOCTL_IN(arg, ret) \ - rc = get_user(ret, (int *)(arg)); \ + rc = get_user(ret, (int __user *)(arg)); \ if (rc) break; #define IOCTL_OUT(arg, ret) \ - ioctl_return2((int *)(arg), ret) + ioctl_return2((int __user *)(arg), ret) -static inline int ioctl_return2(int *addr, int value) +static inline int ioctl_return2(int __user *addr, int value) { return value < 0 ? value : put_user(value, addr); } @@ -457,11 +455,11 @@ tas_dmasound_init(void) &gpio_headphone_detect_pol); write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); - wait_ms(100); + msleep(100); write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); - wait_ms(100); + msleep(100); if (gpio_headphone_irq) { - if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",0) < 0) { + if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) { printk(KERN_ERR "tumbler: Can't request headphone interrupt\n"); gpio_headphone_irq = 0; } else { @@ -470,7 +468,7 @@ tas_dmasound_init(void) val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0); pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80); /* Trigger it */ - headphone_intr(0,0,0); + headphone_intr(0,NULL,NULL); } } if (!gpio_headphone_irq) { @@ -487,7 +485,7 @@ static int tas_dmasound_cleanup(void) { if (gpio_headphone_irq) - free_irq(gpio_headphone_irq, 0); + free_irq(gpio_headphone_irq, NULL); return 0; } @@ -514,6 +512,7 @@ tas_set_frame_rate(void) static int tas_mixer_ioctl(u_int cmd, u_long arg) { + int __user *argp = (int __user *)arg; int data; int rc; @@ -524,16 +523,16 @@ tas_mixer_ioctl(u_int cmd, u_long arg) if ((cmd & ~0xff) == MIXER_WRITE(0) && tas_supported_mixers() & (1<<(cmd & 0xff))) { - rc = get_user(data, (int *)(arg)); + rc = get_user(data, argp); if (rc<0) return rc; tas_set_mixer_level(cmd & 0xff, data); tas_get_mixer_level(cmd & 0xff, &data); - return ioctl_return2((int *)(arg), data); + return ioctl_return2(argp, data); } if ((cmd & ~0xff) == MIXER_READ(0) && tas_supported_mixers() & (1<<(cmd & 0xff))) { tas_get_mixer_level(cmd & 0xff, &data); - return ioctl_return2((int *)(arg), data); + return ioctl_return2(argp, data); } switch(cmd) { @@ -614,7 +613,7 @@ tas_init_frame_rates(unsigned int *prop, unsigned int l) /* * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA. */ -static void *PMacAlloc(unsigned int size, int flags) +static void *PMacAlloc(unsigned int size, gfp_t flags) { return kmalloc(size, flags); } @@ -627,10 +626,10 @@ static void PMacFree(void *ptr, unsigned int size) static int __init PMacIrqInit(void) { if (awacs) - if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0)) + if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL)) return 0; - if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0) - || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", 0)) + if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL) + || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL)) return 0; return 1; } @@ -653,33 +652,32 @@ static void PMacIrqCleanup(void) machine_is_compatible("PowerBook3,2")) && awacs) { awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; awacs_write(MASK_ADDR1 | awacs_reg[1]); - wait_ms(200); + msleep(200); } if (awacs) - free_irq(awacs_irq, 0); - free_irq(awacs_tx_irq, 0); - free_irq(awacs_rx_irq, 0); + free_irq(awacs_irq, NULL); + free_irq(awacs_tx_irq, NULL); + free_irq(awacs_rx_irq, NULL); if (awacs) - iounmap((void *)awacs); + iounmap(awacs); if (i2s) - iounmap((void *)i2s); - iounmap((void *)awacs_txdma); - iounmap((void *)awacs_rxdma); - - release_OF_resource(awacs_node, 0); - release_OF_resource(awacs_node, 1); - release_OF_resource(awacs_node, 2); - - if (awacs_tx_cmd_space) - kfree(awacs_tx_cmd_space); - if (awacs_rx_cmd_space) - kfree(awacs_rx_cmd_space); - if (beep_dbdma_cmd_space) - kfree(beep_dbdma_cmd_space); - if (beep_buf) - kfree(beep_buf); -#ifdef CONFIG_PMAC_PBOOK + iounmap(i2s); + iounmap(awacs_txdma); + iounmap(awacs_rxdma); + + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + release_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1); + + kfree(awacs_tx_cmd_space); + kfree(awacs_rx_cmd_space); + kfree(beep_dbdma_cmd_space); + kfree(beep_buf); +#ifdef CONFIG_PM pmu_unregister_sleep_notifier(&awacs_sleep_notifier); #endif } @@ -775,10 +773,10 @@ awacs_recalibrate(void) /* Sorry for the horrible delays... I hope to get that improved * by making the whole PM process asynchronous in a future version */ - wait_ms(750); + msleep(750); awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE; awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1); - wait_ms(1000); + msleep(1000); awacs_write(awacs_reg[1] | MASK_ADDR1); } @@ -1405,9 +1403,9 @@ load_awacs(void) if (awacs_revision == AWACS_SCREAMER) { awacs_write(awacs_reg[5] + MASK_ADDR5); - wait_ms(100); + msleep(100); awacs_write(awacs_reg[6] + MASK_ADDR6); - wait_ms(2); + msleep(2); awacs_write(awacs_reg[1] + MASK_ADDR1); awacs_write(awacs_reg[7] + MASK_ADDR7); } @@ -1419,7 +1417,7 @@ load_awacs(void) } } -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM /* * Save state when going to sleep, restore it afterwards. */ @@ -1479,7 +1477,7 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) machine_is_compatible("PowerBook3,2")) && awacs) { awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; awacs_write(MASK_ADDR1 | awacs_reg[1]); - wait_ms(200); + msleep(200); } break; case PBOOK_WAKE: @@ -1487,12 +1485,12 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1); if ((machine_is_compatible("PowerBook3,1") || machine_is_compatible("PowerBook3,2")) && awacs) { - wait_ms(100); + msleep(100); awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1); awacs_write(MASK_ADDR1 | awacs_reg[1]); - wait_ms(300); + msleep(300); } else - wait_ms(1000); + msleep(1000); /* restore settings */ switch (awacs_revision) { case AWACS_TUMBLER: @@ -1500,14 +1498,14 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); - wait_ms(100); + msleep(100); write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); - wait_ms(150); + msleep(150); tas_leave_sleep(); /* Stub for now */ - headphone_intr(0,0,0); + headphone_intr(0,NULL,NULL); break; case AWACS_DACA: - wait_ms(10); /* Check this !!! */ + msleep(10); /* Check this !!! */ daca_leave_sleep(); break ; /* dont know how yet */ case AWACS_BURGUNDY: @@ -1555,13 +1553,13 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) } return PBOOK_SLEEP_OK; } -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* All the burgundy functions: */ /* Waits for busy flag to clear */ -inline static void +static inline void awacs_burgundy_busy_wait(void) { int count = 50; /* > 2 samples at 44k1 */ @@ -1569,7 +1567,7 @@ awacs_burgundy_busy_wait(void) udelay(1) ; } -inline static void +static inline void awacs_burgundy_extend_wait(void) { int count = 50 ; /* > 2 samples at 44k1 */ @@ -2301,8 +2299,7 @@ if (count <= 0) #endif if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) { - if (awacs_tx_cmd_space) - kfree(awacs_tx_cmd_space); + kfree(awacs_tx_cmd_space); number_of_tx_cmd_buffers = 0; /* we need nbufs + 1 (for the loop) and we should request + 1 @@ -2360,8 +2357,7 @@ if (count <= 0) #endif if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) { - if (awacs_rx_cmd_space) - kfree(awacs_rx_cmd_space); + kfree(awacs_rx_cmd_space); number_of_rx_cmd_buffers = 0; /* we need nbufs + 1 (for the loop) and we should request + 1 again @@ -2432,7 +2428,7 @@ static void PMacAbortRead(void) * release the memory. */ - wait_ms(100) ; /* give it a (small) chance to act */ + msleep(100) ; /* give it a (small) chance to act */ /* apply the sledgehammer approach - just stop it now */ @@ -2802,32 +2798,23 @@ __init setup_beep(void) DBDMA_ALIGN(beep_dbdma_cmd_space); /* set up emergency dbdma cmd */ emergency_dbdma_cmd = beep_dbdma_cmd+1 ; - beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); + beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); if (beep_buf == NULL) { printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); - if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ; + kfree(beep_dbdma_cmd_space) ; return -ENOMEM ; } return 0 ; } -static struct input_dev awacs_beep_dev = { - .evbit = { BIT(EV_SND) }, - .sndbit = { BIT(SND_BELL) | BIT(SND_TONE) }, - .event = awacs_beep_event, - .name = "dmasound beeper", - .phys = "macio/input0", /* what the heck is this?? */ - .id = { - .bustype = BUS_HOST, - }, -}; +static struct input_dev *awacs_beep_dev; int __init dmasound_awacs_init(void) { struct device_node *io = NULL, *info = NULL; int vol, res; - if (_machine != _MACH_Pmac) + if (!machine_is(powermac)) return -ENODEV; awacs_subframe = 0; @@ -2878,51 +2865,76 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n"); * other info if necessary (early AWACS we want to read chip ids) */ - if (io->n_addrs < 3 || io->n_intrs < 3) { + if (of_get_address(io, 2, NULL, NULL) == NULL || io->n_intrs < 3) { /* OK - maybe we need to use the 'awacs' node (on earlier * machines). - */ + */ if (awacs_node) { io = awacs_node ; - if (io->n_addrs < 3 || io->n_intrs < 3) { - printk("dmasound_pmac: can't use %s" - " (%d addrs, %d intrs)\n", - io->full_name, io->n_addrs, io->n_intrs); + if (of_get_address(io, 2, NULL, NULL) == NULL || + io->n_intrs < 3) { + printk("dmasound_pmac: can't use %s\n", + io->full_name); return -ENODEV; } - } else { - printk("dmasound_pmac: can't use %s (%d addrs, %d intrs)\n", - io->full_name, io->n_addrs, io->n_intrs); - } + } else + printk("dmasound_pmac: can't use %s\n", io->full_name); } - if (!request_OF_resource(io, 0, NULL)) { + if (of_address_to_resource(io, 0, &awacs_rsrc[0]) || + request_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1, + " (IO)") == NULL) { printk(KERN_ERR "dmasound: can't request IO resource !\n"); return -ENODEV; } - if (!request_OF_resource(io, 1, " (tx dma)")) { - release_OF_resource(io, 0); - printk(KERN_ERR "dmasound: can't request TX DMA resource !\n"); + if (of_address_to_resource(io, 1, &awacs_rsrc[1]) || + request_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1, + " (tx dma)") == NULL) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n"); return -ENODEV; } - - if (!request_OF_resource(io, 2, " (rx dma)")) { - release_OF_resource(io, 0); - release_OF_resource(io, 1); - printk(KERN_ERR "dmasound: can't request RX DMA resource !\n"); + if (of_address_to_resource(io, 2, &awacs_rsrc[2]) || + request_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1, + " (rx dma)") == NULL) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n"); return -ENODEV; } + awacs_beep_dev = input_allocate_device(); + if (!awacs_beep_dev) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + release_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1); + printk(KERN_ERR "dmasound: can't allocate input device !\n"); + return -ENOMEM; + } + + awacs_beep_dev->name = "dmasound beeper"; + awacs_beep_dev->phys = "macio/input0"; + awacs_beep_dev->id.bustype = BUS_HOST; + awacs_beep_dev->event = awacs_beep_event; + awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + awacs_beep_dev->evbit[0] = BIT(EV_SND); + /* all OF versions I've seen use this value */ if (i2s_node) - i2s = (u32 *)ioremap(io->addrs[0].address, 0x1000); + i2s = ioremap(awacs_rsrc[0].start, 0x1000); else - awacs = (volatile struct awacs_regs *) - ioremap(io->addrs[0].address, 0x1000); - awacs_txdma = (volatile struct dbdma_regs *) - ioremap(io->addrs[1].address, 0x100); - awacs_rxdma = (volatile struct dbdma_regs *) - ioremap(io->addrs[2].address, 0x100); + awacs = ioremap(awacs_rsrc[0].start, 0x1000); + awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100); + awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100); /* first of all make sure that the chip is powered up....*/ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); @@ -2969,7 +2981,7 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); sound_device_id = 0; /* device ID appears post g3 b&w */ - prop = (unsigned int *)get_property(info, "device-id", 0); + prop = (unsigned int *)get_property(info, "device-id", NULL); if (prop != 0) sound_device_id = *prop; @@ -2990,10 +3002,13 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); set_hw_byteswap(io) ; /* figure out if the h/w can do it */ - /* get default volume from nvram - * vol = (~nvram_read_byte(0x1308) & 7) << 1; - */ +#ifdef CONFIG_NVRAM + /* get default volume from nvram */ vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 ); +#else + vol = 0; +#endif + /* set up tracking values */ spk_vol = vol * 100 ; spk_vol /= 7 ; /* get set value to a percentage */ @@ -3059,9 +3074,9 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); if ((res=setup_beep())) return res ; -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM pmu_register_sleep_notifier(&awacs_sleep_notifier); -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* Powerbooks have odd ways of enabling inputs such as an expansion-bay CD or sound from an internal modem @@ -3075,17 +3090,17 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); * sound input. The 0x100 enables the SCSI bus * terminator power. */ - latch_base = (unsigned char *) ioremap (0xf301a000, 0x1000); + latch_base = ioremap (0xf301a000, 0x1000); in_8(latch_base + 0x190); } else if (is_pbook_g3) { struct device_node* mio; - macio_base = 0; + macio_base = NULL; for (mio = io->parent; mio; mio = mio->parent) { - if (strcmp(mio->name, "mac-io") == 0 - && mio->n_addrs > 0) { - macio_base = (unsigned char *) ioremap - (mio->addrs[0].address, 0x40); + if (strcmp(mio->name, "mac-io") == 0) { + struct resource r; + if (of_address_to_resource(mio, 0, &r) == 0) + macio_base = ioremap(r.start, 0x40); break; } } @@ -3147,14 +3162,14 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); * XXX: we should handle errors here, but that would mean * rewriting the whole init code. later.. */ - input_register_device(&awacs_beep_dev); + input_register_device(awacs_beep_dev); return dmasound_init(); } static void __exit dmasound_awacs_cleanup(void) { - input_unregister_device(&awacs_beep_dev); + input_unregister_device(awacs_beep_dev); switch (awacs_revision) { case AWACS_TUMBLER: