X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=sound%2Fparisc%2Fharmony.c;h=0c02a5f458ec346cf4bb51a002a970aa5d701420;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=423ab05c0480f0003f2d88375d94543ea6be4061;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 423ab05c0..0c02a5f45 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -6,7 +6,7 @@ * * Harmony is found in HP 712s, 715/new and many other GSC based machines. * On older 715 machines you'll find the technically identical chip - * called 'Vivace'. Both Harmony and Vicace are supported by this driver. + * called 'Vivace'. Both Harmony and Vivace are supported by this driver. * * this ALSA driver is based on OSS driver by: * Copyright 2000 (c) Linuxcare Canada, Alex deVries @@ -43,7 +43,7 @@ * to be recorded is put in RNXTADD. There is 2 read-only registers, PCURADD and * RCURADD that provides adress of current page. * - * Harmony has no way to controll full duplex or half duplex mode. It means + * Harmony has no way to control full duplex or half duplex mode. It means * that we always need to provide adresses of playback and capture data, even * when this is not needed. That's why we statically alloc one graveyard * buffer (to put recorded data in play-only mode) and a silence buffer. @@ -80,8 +80,7 @@ MODULE_AUTHOR("Laurent Canet "); MODULE_DESCRIPTION("ALSA Harmony sound driver"); MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -MODULE_DEVICES("{{ALSA,Harmony soundcard}}"); +MODULE_SUPPORTED_DEVICE("{{ALSA,Harmony soundcard}}"); #undef DEBUG #ifdef DEBUG @@ -138,13 +137,10 @@ static int boot_devs; module_param_array(index, int, boot_devs, 0444); MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard."); -MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC); module_param_array(id, charp, boot_devs, 0444); MODULE_PARM_DESC(id, "ID string for Sun CS4231 soundcard."); -MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); module_param_array(enable, bool, boot_devs, 0444); MODULE_PARM_DESC(enable, "Enable Sun CS4231 soundcard."); -MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); /* Register offset (from base hpa) */ #define REG_ID 0x00 @@ -216,7 +212,6 @@ typedef struct snd_card_harmony { snd_pcm_substream_t *capture_substream; snd_info_entry_t *proc_entry; } snd_card_harmony_t; -#define chip_t snd_card_harmony_t static snd_card_t *snd_harmony_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; @@ -243,10 +238,8 @@ static unsigned int snd_card_harmony_rates[] = { 44100, 48000 }; -#define RATES sizeof(snd_card_harmony_rates) / sizeof(snd_card_harmony_rates[0]) - static snd_pcm_hw_constraint_list_t hw_constraint_rates = { - .count = RATES, + .count = ARRAY_SIZE(snd_card_harmony_rates), .list = snd_card_harmony_rates, .mask = 0, }; @@ -283,7 +276,7 @@ static unsigned int snd_card_harmony_rate_bits(int rate) { unsigned int idx; - for (idx = 0; idx <= RATES; idx++) + for (idx = 0; idx <= ARRAY_SIZE(snd_card_harmony_rates); idx++) if (snd_card_harmony_rates[idx] == rate) return rate_bits[idx]; return HARMONY_SR_44KHZ; /* fallback */ @@ -556,7 +549,7 @@ static int snd_card_harmony_playback_prepare(snd_pcm_substream_t * substream) harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate); /* data format */ - harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format); + harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format); /* number of channels */ if (runtime->channels == 2) @@ -587,7 +580,7 @@ static int snd_card_harmony_capture_prepare(snd_pcm_substream_t * substream) harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate); /* data format */ - harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format); + harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format); /* number of channels */ if (runtime->channels == 1) @@ -751,6 +744,8 @@ static int snd_card_harmony_hw_params(snd_pcm_substream_t *substream, int err; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + if (err > 0 && substream->dma_device.type == SNDRV_DMA_TYPE_CONTINUOUS) + substream->runtime->dma_addr = __pa(substream->runtime->dma_area); DPRINTK(KERN_INFO PFX "HW Params returned %d, dma_addr %lx\n", err, (unsigned long)substream->runtime->dma_addr); return err; @@ -784,7 +779,7 @@ static snd_pcm_ops_t snd_card_harmony_capture_ops = { .pointer = snd_card_harmony_capture_pointer, }; -static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony, int device) +static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony) { snd_pcm_t *pcm; int err; @@ -797,7 +792,7 @@ static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony, int device) snd_harmony_disable_interrupts(harmony); - if ((err = snd_pcm_new(harmony->card, "Harmony", device, 1, 1, &pcm)) < 0) + if ((err = snd_pcm_new(harmony->card, "Harmony", 0, 1, 1, &pcm)) < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_harmony_playback_ops); @@ -811,28 +806,54 @@ static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony, int device) /* initialize graveyard buffer */ harmony->dma_dev.type = SNDRV_DMA_TYPE_DEV; harmony->dma_dev.dev = &harmony->pa_dev->dev; - err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*GRAVEYARD_BUFS, + err = snd_dma_alloc_pages(harmony->dma_dev.type, + harmony->dma_dev.dev, + HARMONY_BUF_SIZE*GRAVEYARD_BUFS, &harmony->graveyard_dma); - if (err < 0) + if (err == -ENOMEM) { + /* use continuous buffers */ + harmony->dma_dev.type = SNDRV_DMA_TYPE_CONTINUOUS; + harmony->dma_dev.dev = snd_dma_continuous_data(GFP_KERNEL); + err = snd_dma_alloc_pages(harmony->dma_dev.type, + harmony->dma_dev.dev, + HARMONY_BUF_SIZE*GRAVEYARD_BUFS, + &harmony->graveyard_dma); + } + if (err < 0) { + printk(KERN_ERR PFX "can't allocate graveyard buffer\n"); return err; + } harmony->graveyard_count = 0; /* initialize silence buffers */ - err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*SILENCE_BUFS, + err = snd_dma_alloc_pages(harmony->dma_dev.type, + harmony->dma_dev.dev, + HARMONY_BUF_SIZE*SILENCE_BUFS, &harmony->silence_dma); - if (err < 0) + if (err < 0) { + printk(KERN_ERR PFX "can't allocate silence buffer\n"); return err; + } harmony->silence_count = 0; + if (harmony->dma_dev.type == SNDRV_DMA_TYPE_CONTINUOUS) { + harmony->graveyard_dma.addr = __pa(harmony->graveyard_dma.area); + harmony->silence_dma.addr = __pa(harmony->silence_dma.area); + } + harmony->ply_stopped = harmony->cap_stopped = 1; harmony->playback_substream = NULL; harmony->capture_substream = NULL; harmony->graveyard_count = 0; - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - &harmony->pa_dev->dev, - MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); + + err = snd_pcm_lib_preallocate_pages_for_all(pcm, harmony->dma_dev.type, + harmony->dma_dev.dev, + MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); + if (err < 0) { + printk(KERN_ERR PFX "buffer allocation error %d\n", err); + // return err; + } return 0; } @@ -871,7 +892,7 @@ static int snd_harmony_mixercontrol_info(snd_kcontrol_t * kcontrol, snd_ctl_elem static int snd_harmony_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - snd_card_harmony_t *harmony = _snd_kcontrol_chip(kcontrol); + snd_card_harmony_t *harmony = snd_kcontrol_chip(kcontrol); int shift_left = (kcontrol->private_value) & 0xff; int shift_right = (kcontrol->private_value >> 8) & 0xff; int mask = (kcontrol->private_value >> 16) & 0xff; @@ -896,7 +917,7 @@ static int snd_harmony_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ static int snd_harmony_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - snd_card_harmony_t *harmony = _snd_kcontrol_chip(kcontrol); + snd_card_harmony_t *harmony = snd_kcontrol_chip(kcontrol); int shift_left = (kcontrol->private_value) & 0xff; int shift_right = (kcontrol->private_value >> 8) & 0xff; int mask = (kcontrol->private_value >> 16) & 0xff; @@ -1037,7 +1058,7 @@ static int __init snd_card_harmony_probe(struct parisc_device *pa_dev) snd_card_free(card); return err; } - if ((err = snd_card_harmony_pcm_init(chip, dev)) < 0) { + if ((err = snd_card_harmony_pcm_init(chip)) < 0) { printk(KERN_ERR PFX "PCM Init failed\n"); snd_card_free(card); return err;