From 9bd6a73aef955216816fd6e28f371a868ed073d5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:55:19 +0200 Subject: ALSA: oxygen: use a copy of the model struct Put a copy of the model structure into the chip structure so that model- specific drivers can modify it depending on a particular device instance. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen_lib.c | 54 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 22f37851045e..07b0563cc903 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -161,8 +161,8 @@ static void oxygen_gpio_changed(struct work_struct *work) { struct oxygen *chip = container_of(work, struct oxygen, gpio_work); - if (chip->model->gpio_changed) - chip->model->gpio_changed(chip); + if (chip->model.gpio_changed) + chip->model.gpio_changed(chip); } #ifdef CONFIG_PROC_FS @@ -221,7 +221,7 @@ static void oxygen_init(struct oxygen *chip) chip->dac_routing = 1; for (i = 0; i < 8; ++i) - chip->dac_volume[i] = chip->model->dac_volume_min; + chip->dac_volume[i] = chip->model.dac_volume_min; chip->dac_mute = 1; chip->spdif_playback_enable = 1; chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL | @@ -243,7 +243,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_write8_masked(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC | - chip->model->function_flags, + chip->model.function_flags, OXYGEN_FUNCTION_RESET_CODEC | OXYGEN_FUNCTION_2WIRE_SPI_MASK | OXYGEN_FUNCTION_ENABLE_SPI_4_5); @@ -255,7 +255,7 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_DMA_MULTICH_BURST_8); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); oxygen_write8_masked(chip, OXYGEN_MISC, - chip->model->misc_flags, + chip->model.misc_flags, OXYGEN_MISC_WRITE_PCI_SUBID | OXYGEN_MISC_REC_C_FROM_SPDIF | OXYGEN_MISC_REC_B_FROM_AC97 | @@ -270,21 +270,21 @@ static void oxygen_init(struct oxygen *chip) (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_RATE_48000 | chip->model->dac_i2s_format | + OXYGEN_RATE_48000 | chip->model.dac_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); - if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_RATE_48000 | chip->model->adc_i2s_format | + OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); - if (chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | - CAPTURE_2_FROM_I2S_2)) + if (chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | + CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_RATE_48000 | chip->model->adc_i2s_format | + OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); else @@ -295,7 +295,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); - if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_SENSE_MASK | OXYGEN_SPDIF_LOCK_MASK | @@ -417,7 +417,7 @@ static void oxygen_card_free(struct snd_card *card) if (chip->irq >= 0) free_irq(chip->irq, chip); flush_scheduled_work(); - chip->model->cleanup(chip); + chip->model.cleanup(chip); mutex_destroy(&chip->mutex); pci_release_regions(chip->pci); pci_disable_device(chip->pci); @@ -439,7 +439,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, chip->card = card; chip->pci = pci; chip->irq = -1; - chip->model = model; + chip->model = *model; chip->model_data = chip + 1; spin_lock_init(&chip->reg_lock); mutex_init(&chip->mutex); @@ -471,22 +471,22 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, card->private_free = oxygen_card_free; oxygen_init(chip); - model->init(chip); + chip->model.init(chip); err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED, - model->chip, chip); + chip->model.chip, chip); if (err < 0) { snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq); goto err_card; } chip->irq = pci->irq; - strcpy(card->driver, model->chip); - strcpy(card->shortname, model->shortname); + strcpy(card->driver, chip->model.chip); + strcpy(card->shortname, chip->model.shortname); sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", - model->longname, chip->revision, chip->addr, chip->irq); - strcpy(card->mixername, model->chip); - snd_component_add(card, model->chip); + chip->model.longname, chip->revision, chip->addr, chip->irq); + strcpy(card->mixername, chip->model.chip); + snd_component_add(card, chip->model.chip); err = oxygen_pcm_init(chip); if (err < 0) @@ -496,7 +496,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, if (err < 0) goto err_card; - if (model->misc_flags & OXYGEN_MISC_MIDI) { + if (chip->model.misc_flags & OXYGEN_MISC_MIDI) { err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, chip->addr + OXYGEN_MPU401, MPU401_INFO_INTEGRATED, 0, 0, @@ -508,7 +508,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, oxygen_proc_init(chip); spin_lock_irq(&chip->reg_lock); - if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT; if (chip->has_ac97_0 | chip->has_ac97_1) chip->interrupt_mask |= OXYGEN_INT_AC97; @@ -552,8 +552,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) if (chip->streams[i]) snd_pcm_suspend(chip->streams[i]); - if (chip->model->suspend) - chip->model->suspend(chip); + if (chip->model.suspend) + chip->model.suspend(chip); spin_lock_irq(&chip->reg_lock); saved_interrupt_mask = chip->interrupt_mask; @@ -624,8 +624,8 @@ int oxygen_pci_resume(struct pci_dev *pci) if (chip->has_ac97_1) oxygen_restore_ac97(chip, 1); - if (chip->model->resume) - chip->model->resume(chip); + if (chip->model.resume) + chip->model.resume(chip); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); -- cgit v1.2.3 From 568c59e722da22c9b0a485c2f1aaf28cb1b36b79 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:56:01 +0200 Subject: ALSA: oxygen: add probe callback Add a probe callback to the model structure so that model-specific drivers can refine their model detection before the card is initialized. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/hifier.c | 2 +- sound/pci/oxygen/oxygen.c | 3 ++- sound/pci/oxygen/oxygen.h | 4 +++- sound/pci/oxygen/oxygen_lib.c | 8 +++++++- sound/pci/oxygen/virtuoso.c | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index dad393ae040a..173d6dddc937 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -180,7 +180,7 @@ static int __devinit hifier_probe(struct pci_dev *pci, ++dev; return -ENOENT; } - err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier); + err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0); if (err >= 0) ++dev; return err; diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index c5829d30ef86..4722fe08dca8 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -354,7 +354,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, } is_meridian = pci_id->driver_data; err = oxygen_pci_probe(pci, index[dev], id[dev], - is_meridian ? &model_meridian : &model_generic); + is_meridian ? &model_meridian : &model_generic, + 0); if (err >= 0) ++dev; return err; diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 5f3fbf802222..914b8f406b14 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -58,6 +58,7 @@ struct oxygen_model { const char *longname; const char *chip; struct module *owner; + int (*probe)(struct oxygen *chip, unsigned long driver_data); void (*init)(struct oxygen *chip); int (*control_filter)(struct snd_kcontrol_new *template); int (*mixer_init)(struct oxygen *chip); @@ -125,7 +126,8 @@ struct oxygen { /* oxygen_lib.c */ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, - const struct oxygen_model *model); + const struct oxygen_model *model, + unsigned long driver_data); void oxygen_pci_remove(struct pci_dev *pci); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 07b0563cc903..58bbc010ed89 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -424,7 +424,8 @@ static void oxygen_card_free(struct snd_card *card) } int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, - const struct oxygen_model *model) + const struct oxygen_model *model, + unsigned long driver_data) { struct snd_card *card; struct oxygen *chip; @@ -470,6 +471,11 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, snd_card_set_dev(card, &pci->dev); card->private_free = oxygen_card_free; + if (chip->model.probe) { + err = chip->model.probe(chip, driver_data); + if (err < 0) + goto err_card; + } oxygen_init(chip); chip->model.init(chip); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 01d7b75f9182..4aa2857a1b05 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -696,7 +696,7 @@ static int __devinit xonar_probe(struct pci_dev *pci, return -ENOENT; } err = oxygen_pci_probe(pci, index[dev], id[dev], - &xonar_models[pci_id->driver_data]); + &xonar_models[pci_id->driver_data], 0); if (err >= 0) ++dev; return err; -- cgit v1.2.3 From d76596b1ee7f5cdbd0b73d374ba72372a2c8b725 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:02:08 +0200 Subject: ALSA: oxygen: rename pcm_dev_cfg Rename the pcm_dev_cfg field to device_config because there will be additional flags that do not describe PCM devices. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/hifier.c | 6 +++--- sound/pci/oxygen/oxygen.c | 20 ++++++++++---------- sound/pci/oxygen/oxygen.h | 2 +- sound/pci/oxygen/oxygen_lib.c | 10 +++++----- sound/pci/oxygen/oxygen_mixer.c | 4 ++-- sound/pci/oxygen/oxygen_pcm.c | 24 ++++++++++++------------ sound/pci/oxygen/virtuoso.c | 14 +++++++------- 7 files changed, 40 insertions(+), 40 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 173d6dddc937..088939903ee2 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -157,9 +157,9 @@ static const struct oxygen_model model_hifier = { .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct hifier_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1, .dac_channels = 2, .dac_volume_min = 0, .dac_volume_max = 255, diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 043fe281358e..bb2e7d82d832 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -292,10 +292,10 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data) chip->model.init = meridian_init; chip->model.resume = ak4396_registers_init; chip->model.set_adc_params = set_ak5385_params; - chip->model.pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF; + chip->model.device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF; chip->model.misc_flags = OXYGEN_MISC_MIDI; } return 0; @@ -316,12 +316,12 @@ static const struct oxygen_model model_generic = { .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct generic_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - PLAYBACK_2_TO_AC97_1 | - CAPTURE_0_FROM_I2S_1 | - CAPTURE_1_FROM_SPDIF | - CAPTURE_2_FROM_AC97_1, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + PLAYBACK_2_TO_AC97_1 | + CAPTURE_0_FROM_I2S_1 | + CAPTURE_1_FROM_SPDIF | + CAPTURE_2_FROM_AC97_1, .dac_channels = 8, .dac_volume_min = 0, .dac_volume_max = 255, diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 914b8f406b14..30cd996d3661 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -78,7 +78,7 @@ struct oxygen_model { unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; size_t model_data_size; - unsigned int pcm_dev_cfg; + unsigned int device_config; u8 dac_channels; u8 dac_volume_min; u8 dac_volume_max; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 58bbc010ed89..02191c6a4e7b 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -273,7 +273,7 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_RATE_48000 | chip->model.dac_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); - if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | @@ -281,8 +281,8 @@ static void oxygen_init(struct oxygen *chip) else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); - if (chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | - CAPTURE_2_FROM_I2S_2)) + if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | + CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | @@ -295,7 +295,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_SENSE_MASK | OXYGEN_SPDIF_LOCK_MASK | @@ -514,7 +514,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, oxygen_proc_init(chip); spin_lock_irq(&chip->reg_lock); - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT; if (chip->has_ac97_0 | chip->has_ac97_1) chip->interrupt_mask |= OXYGEN_INT_AC97; diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index b7226b60eab6..304da169bfdc 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -974,14 +974,14 @@ int oxygen_mixer_init(struct oxygen *chip) err = add_controls(chip, controls, ARRAY_SIZE(controls)); if (err < 0) return err; - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) { + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { err = add_controls(chip, spdif_input_controls, ARRAY_SIZE(spdif_input_controls)); if (err < 0) return err; } for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) { - if (!(chip->model.pcm_dev_cfg & monitor_controls[i].pcm_dev)) + if (!(chip->model.device_config & monitor_controls[i].pcm_dev)) continue; err = add_controls(chip, monitor_controls[i].controls, ARRAY_SIZE(monitor_controls[i].controls)); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 5e8071ac766f..87b60071b616 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -129,7 +129,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->private_data = (void *)(uintptr_t)channel; if (channel == PCM_B && chip->has_ac97_1 && - (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1)) + (chip->model.device_config & CAPTURE_2_FROM_AC97_1)) runtime->hw = oxygen_ac97_hardware; else runtime->hw = *oxygen_hardware[channel]; @@ -381,7 +381,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, return err; is_ac97 = chip->has_ac97_1 && - (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + (chip->model.device_config & CAPTURE_2_FROM_AC97_1); spin_lock_irq(&chip->reg_lock); oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, @@ -657,9 +657,9 @@ int oxygen_pcm_init(struct oxygen *chip) int outs, ins; int err; - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_0_TO_I2S); - ins = !!(chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 | - CAPTURE_0_FROM_I2S_2)); + outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S); + ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 | + CAPTURE_0_FROM_I2S_2)); if (outs | ins) { err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); if (err < 0) @@ -667,10 +667,10 @@ int oxygen_pcm_init(struct oxygen *chip) if (outs) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); - if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_a_ops); - else if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_2) + else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; @@ -690,8 +690,8 @@ int oxygen_pcm_init(struct oxygen *chip) BUFFER_BYTES_MAX); } - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF); + outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF); + ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF); if (outs | ins) { err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); if (err < 0) @@ -712,11 +712,11 @@ int oxygen_pcm_init(struct oxygen *chip) } if (chip->has_ac97_1) { - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_2_TO_AC97_1); - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1); + ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1); } else { outs = 0; - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_I2S_2); + ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2); } if (outs | ins) { err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 34baff19ad36..f416e68338e2 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -566,10 +566,10 @@ static const struct oxygen_model model_xonar_d2 = { .update_dac_mute = update_pcm1796_mute, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF, .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, @@ -598,9 +598,9 @@ static const struct oxygen_model model_xonar_d1 = { .ac97_switch = xonar_d1_ac97_switch, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2, .dac_channels = 8, .dac_volume_min = 0, .dac_volume_max = 127, -- cgit v1.2.3 From dbbbd6744439d95d2b0dc23c5cdca2c477377f76 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:03:42 +0200 Subject: ALSA: oxygen: configure MIDI via device_config To enable the MIDI port, model drivers must now set flags in device_config, not only in misc_flags. This allows model drivers to enable the UART without creating an ALSA MIDI device. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.c | 1 + sound/pci/oxygen/oxygen.h | 21 +++++++++++++-------- sound/pci/oxygen/oxygen_lib.c | 9 +++++++-- sound/pci/oxygen/virtuoso.c | 4 +++- 4 files changed, 24 insertions(+), 11 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index bb2e7d82d832..62888c7b61d4 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -297,6 +297,7 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data) CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; chip->model.misc_flags = OXYGEN_MISC_MIDI; + chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; } return 0; } diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 30cd996d3661..f82a96290f72 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -19,14 +19,19 @@ #define OXYGEN_IO_SIZE 0x100 /* model-specific configuration of outputs/inputs */ -#define PLAYBACK_0_TO_I2S 0x001 -#define PLAYBACK_1_TO_SPDIF 0x004 -#define PLAYBACK_2_TO_AC97_1 0x008 -#define CAPTURE_0_FROM_I2S_1 0x010 -#define CAPTURE_0_FROM_I2S_2 0x020 -#define CAPTURE_1_FROM_SPDIF 0x080 -#define CAPTURE_2_FROM_I2S_2 0x100 -#define CAPTURE_2_FROM_AC97_1 0x200 +#define PLAYBACK_0_TO_I2S 0x0001 + /* PLAYBACK_0_TO_AC97_0 not implemented */ +#define PLAYBACK_1_TO_SPDIF 0x0004 +#define PLAYBACK_2_TO_AC97_1 0x0008 +#define CAPTURE_0_FROM_I2S_1 0x0010 +#define CAPTURE_0_FROM_I2S_2 0x0020 + /* CAPTURE_0_FROM_AC97_0 not implemented */ +#define CAPTURE_1_FROM_SPDIF 0x0080 +#define CAPTURE_2_FROM_I2S_2 0x0100 +#define CAPTURE_2_FROM_AC97_1 0x0200 + /* CAPTURE_3_FROM_I2S_3 not implemented */ +#define MIDI_OUTPUT 0x0800 +#define MIDI_INPUT 0x1000 enum { CONTROL_SPDIF_PCM, diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 02191c6a4e7b..b1997216b4af 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -502,10 +502,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, if (err < 0) goto err_card; - if (chip->model.misc_flags & OXYGEN_MISC_MIDI) { + if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) { + unsigned int info_flags = MPU401_INFO_INTEGRATED; + if (chip->model.device_config & MIDI_OUTPUT) + info_flags |= MPU401_INFO_OUTPUT; + if (chip->model.device_config & MIDI_INPUT) + info_flags |= MPU401_INFO_INPUT; err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, chip->addr + OXYGEN_MPU401, - MPU401_INFO_INTEGRATED, 0, 0, + info_flags, 0, 0, &chip->midi); if (err < 0) goto err_card; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index f416e68338e2..befada742ae8 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -569,7 +569,9 @@ static const struct oxygen_model model_xonar_d2 = { .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, + CAPTURE_1_FROM_SPDIF | + MIDI_OUTPUT | + MIDI_INPUT, .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, -- cgit v1.2.3 From 397b1dcc449082ce3f720c548da9c59db01cb739 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:04:43 +0200 Subject: ALSA: oxygen: add UART I/O functions Add functions to allow model drivers to communicate with external chips by doing I/O with the not-used-for-MIDI UART. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.h | 6 ++++++ sound/pci/oxygen/oxygen_io.c | 21 +++++++++++++++++++++ sound/pci/oxygen/oxygen_lib.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index f82a96290f72..19107c6307e5 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -79,6 +79,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); void (*gpio_changed)(struct oxygen *chip); + void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; @@ -125,6 +126,8 @@ struct oxygen { __le32 _32[OXYGEN_IO_SIZE / 4]; } saved_registers; u16 saved_ac97_registers[2][0x40]; + unsigned int uart_input_count; + u8 uart_input[32]; struct oxygen_model model; }; @@ -174,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data); void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data); +void oxygen_reset_uart(struct oxygen *chip); +void oxygen_write_uart(struct oxygen *chip, u8 data); + static inline void oxygen_set_bits8(struct oxygen *chip, unsigned int reg, u8 value) { diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c index 83f135f80df4..deba7389aec3 100644 --- a/sound/pci/oxygen/oxygen_io.c +++ b/sound/pci/oxygen/oxygen_io.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "oxygen.h" @@ -232,3 +233,23 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) device | OXYGEN_2WIRE_DIR_WRITE); } EXPORT_SYMBOL(oxygen_write_i2c); + +static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) +{ + if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL) + msleep(1); + oxygen_write8(chip, OXYGEN_MPU401 + port, data); +} + +void oxygen_reset_uart(struct oxygen *chip) +{ + _write_uart(chip, 1, MPU401_RESET); + _write_uart(chip, 1, MPU401_ENTER_UART); +} +EXPORT_SYMBOL(oxygen_reset_uart); + +void oxygen_write_uart(struct oxygen *chip, u8 data) +{ + _write_uart(chip, 0, data); +} +EXPORT_SYMBOL(oxygen_write_uart); diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b1997216b4af..84f481d41efa 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library"); MODULE_LICENSE("GPL v2"); +static inline int oxygen_uart_input_ready(struct oxygen *chip) +{ + return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY); +} + +static void oxygen_read_uart(struct oxygen *chip) +{ + if (unlikely(!oxygen_uart_input_ready(chip))) { + /* no data, but read it anyway to clear the interrupt */ + oxygen_read8(chip, OXYGEN_MPU401); + return; + } + do { + u8 data = oxygen_read8(chip, OXYGEN_MPU401); + if (data == MPU401_ACK) + continue; + if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input)) + chip->uart_input_count = 0; + chip->uart_input[chip->uart_input_count++] = data; + } while (oxygen_uart_input_ready(chip)); + if (chip->model.uart_input) + chip->model.uart_input(chip); +} + static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) { struct oxygen *chip = dev_id; @@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) if (status & OXYGEN_INT_GPIO) schedule_work(&chip->gpio_work); - if ((status & OXYGEN_INT_MIDI) && chip->midi) - snd_mpu401_uart_interrupt(0, chip->midi->private_data); + if (status & OXYGEN_INT_MIDI) { + if (chip->midi) + snd_mpu401_uart_interrupt(0, chip->midi->private_data); + else + oxygen_read_uart(chip); + } if (status & OXYGEN_INT_AC97) wake_up(&chip->ac97_waitqueue); -- cgit v1.2.3