static int lola_init_stream(struct lola *chip, struct lola_stream *str, int idx, int nid, int dir) { unsigned int val; int err; str->nid = nid; str->index = idx; str->dsd = idx; if (dir == PLAY) str->dsd += MAX_STREAM_IN_COUNT; err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); if (err < 0) { dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid); return err; } if (dir == PLAY) { /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */ if ((val & 0x00f00dff) != 0x00000010) { dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid); return -EINVAL; } } else { /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) * (bug : ignore bit8: Conn list = 0/1) */ if ((val & 0x00f00cff) != 0x00100010) { dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid); return -EINVAL; } /* test bit9:DIGITAL and bit12:SRC_PRESENT*/ if ((val & 0x00001200) == 0x00001200) chip->input_src_caps_mask |= (1 << idx); } err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val); if (err < 0) { dev_err(chip->card->dev, "Can't read FORMATS 0x%x\n", nid); return err; } val &= 3; if (val == 3) str->can_float = true; if (!(val & 1)) { dev_err(chip->card->dev, "Invalid formats 0x%x for 0x%x", val, nid); return -EINVAL; } return 0; }
int __devinit lola_init_mixer_widget(struct lola *chip, int nid) { unsigned int val; int err; err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); return err; } if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ snd_printdd("No valid mixer widget\n"); return 0; } chip->mixer.nid = nid; chip->mixer.caps = val; chip->mixer.array = (struct lola_mixer_array __iomem *) (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE); /* reserve memory to copy mixer data for sleep mode transitions */ chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array)); /* mixer matrix sources are physical input data and play streams */ chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams; chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins; /* mixer matrix destinations are record streams and physical output */ chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; <<<<<<< HEAD
static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin, int dir, int nid) { unsigned int val; int err; pin->nid = nid; err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); return err; } val &= 0x00f00fff; /* test TYPE and bits 0..11 */ if (val == 0x00400200) /* Type = 4, Digital = 1 */ pin->is_analog = false; else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */ pin->is_analog = true; else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */ pin->is_analog = true; else { printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid); return -EINVAL; } /* analog parameters only following, so continue in case of Digital pin */ if (!pin->is_analog) return 0; if (dir == PLAY) err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val); else err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid); return err; } pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val); pin->amp_step_size = LOLA_AMP_STEP_SIZE(val); pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val); if (pin->amp_num_steps) { /* zero as mute state */ pin->amp_num_steps++; pin->amp_step_size++; } pin->amp_offset = LOLA_AMP_OFFSET(val); err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL); if (err < 0) { printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid); return err; } pin->max_level = val & 0x3ff; /* 10 bits */ pin->config_default_reg = 0; pin->fixed_gain_list_len = 0; pin->cur_gain_step = 0; return 0; }
int __devinit lola_init_mixer_widget(struct lola *chip, int nid) { unsigned int val; int err; err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); return err; } if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ snd_printdd("No valid mixer widget\n"); return 0; } chip->mixer.nid = nid; chip->mixer.caps = val; chip->mixer.array = (struct lola_mixer_array __iomem *) (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE); /* reserve memory to copy mixer data for sleep mode transitions */ chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array)); /* mixer matrix sources are physical input data and play streams */ chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams; chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins; /* mixer matrix destinations are record streams and physical output */ chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; /* mixer matrix may have unused areas between PhysIn and * Play or Record and PhysOut zones */ chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val); /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones) * +-+ 0-------8------16-------8------16 * | | | | | | | * |s| | INPUT | | INPUT | | * | |->| -> |unused | -> |unused | * |r| |CAPTURE| | OUTPUT| | * | | | MIX | | MIX | | * |c| 8-------------------------------- * | | | | | | | * | | | | | | | * |g| |unused |unused |unused |unused | * | | | | | | | * |a| | | | | | * | | 16------------------------------- * |i| | | | | | * | | | PLAYBK| | PLAYBK| | * |n|->| -> |unused | -> |unused | * | | |CAPTURE| | OUTPUT| | * | | | MIX | | MIX | | * |a| 8-------------------------------- * |r| | | | | | * |r| | | | | | * |a| |unused |unused |unused |unused | * |y| | | | | | * | | | | | | | * +++ 16--|---------------|------------ * +---V---------------V-----------+ * | dest_mix_gain_enable array | * +-------------------------------+ */ /* example : MixerMatrix of LoLa280 * +-+ 0-------8-2 * | | | | | * |s| | INPUT | | INPUT * |r|->| -> | | -> * |c| |CAPTURE| | <- OUTPUT * | | | MIX | | MIX * |g| 8---------- * |a| | | | * |i| | PLAYBK| | PLAYBACK * |n|->| -> | | -> * | | |CAPTURE| | <- OUTPUT * |a| | MIX | | MIX * |r| 8---|----|- * |r| +---V----V-------------------+ * |a| | dest_mix_gain_enable array | * |y| +----------------------------+ */ if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { printk(KERN_ERR SFX "Invalid mixer widget size\n"); return -EINVAL; } chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) | (((1U << chip->mixer.src_stream_outs) - 1) << chip->mixer.src_stream_out_ofs); chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) | (((1U << chip->mixer.dest_phys_outs) - 1) << chip->mixer.dest_phys_out_ofs); snd_printdd("Mixer src_mask=%x, dest_mask=%x\n", chip->mixer.src_mask, chip->mixer.dest_mask); return 0; }
static int __devinit lola_parse_tree(struct lola *chip) { unsigned int val; int nid, err; err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read VENDOR_ID\n"); return err; } val >>= 16; if (val != 0x1369) { printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val); return -EINVAL; } err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid); return err; } if (val != 1) { printk(KERN_ERR SFX "Unknown function type %d\n", val); return -EINVAL; } err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val); if (err < 0) { printk(KERN_ERR SFX "Can't read SPECCAPS\n"); return err; } chip->lola_caps = val; chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps); chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps); snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n", chip->lola_caps, chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins); if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT || chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) { printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val); return -EINVAL; } nid = 0x02; err = lola_init_pcm(chip, CAPT, &nid); if (err < 0) return err; err = lola_init_pcm(chip, PLAY, &nid); if (err < 0) return err; err = lola_init_pins(chip, CAPT, &nid); if (err < 0) return err; err = lola_init_pins(chip, PLAY, &nid); if (err < 0) return err; if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) { err = lola_init_clock_widget(chip, nid); if (err < 0) return err; nid++; } if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) { err = lola_init_mixer_widget(chip, nid); if (err < 0) return err; nid++; } /* */ err = lola_enable_clock_events(chip); if (err < 0) return err; /* */ if (!chip->cold_reset) { lola_reset_setups(chip); chip->cold_reset = 1; } else { /* */ if (chip->granularity != LOLA_GRANULARITY_MIN) lola_set_granularity(chip, chip->granularity, true); } return 0; }