static int snd_msndmix_set_mux(struct snd_msnd *chip, int val) { unsigned newrecsrc; int change; unsigned char msndbyte; switch (val) { case 0: newrecsrc = MSND_MASK_IMIX; msndbyte = HDEXAR_SET_ANA_IN; break; case 1: newrecsrc = MSND_MASK_SYNTH; msndbyte = HDEXAR_SET_SYNTH_IN; break; case 2: newrecsrc = MSND_MASK_DIGITAL; msndbyte = HDEXAR_SET_DAT_IN; break; default: return -EINVAL; } change = newrecsrc != chip->recsrc; if (change) { change = 0; if (!snd_msnd_send_word(chip, 0, 0, msndbyte)) if (!snd_msnd_send_dsp_cmd(chip, HDEX_AUX_REQ)) { chip->recsrc = newrecsrc; change = 1; } } return change; }
static int __devinit snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate) { snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate); writew(srate, chip->SMA + SMA_wCalFreqAtoD); if (chip->calibrate_signal == 0) writew(readw(chip->SMA + SMA_wCurrHostStatusFlags) | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags); else writew(readw(chip->SMA + SMA_wCurrHostStatusFlags) & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags); if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 && snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) { schedule_timeout_interruptible(msecs_to_jiffies(333)); return 0; } printk(KERN_WARNING LOGNAME ": ADC calibration failed\n"); return -EIO; }
int snd_msnd_upload_host(struct snd_msnd *dev, const u8 *bin, int len) { int i; if (len % 3 != 0) { snd_printk(KERN_ERR LOGNAME ": Upload host data not multiple of 3!\n"); return -EINVAL; } for (i = 0; i < len; i += 3) if (snd_msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2])) return -EIO; inb(dev->io + HP_RXL); inb(dev->io + HP_CVR); return 0; }
static int snd_msndmix_set(struct snd_msnd *dev, int d, int left, int right) { int bLeft, bRight; int wLeft, wRight; int updatemaster = 0; if (d >= LEVEL_ENTRIES) return -EINVAL; bLeft = left * 0xff / 100; wLeft = left * 0xffff / 100; bRight = right * 0xff / 100; wRight = right * 0xffff / 100; dev->left_levels[d] = wLeft; dev->right_levels[d] = wRight; switch (d) { /* master volume unscaled controls */ case MSND_MIXER_LINE: /* line pot control */ /* scaled by IMIX in digital mix */ writeb(bLeft, dev->SMA + SMA_bInPotPosLeft); writeb(bRight, dev->SMA + SMA_bInPotPosRight); if (snd_msnd_send_word(dev, 0, 0, HDEXAR_IN_SET_POTS) == 0) snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); break; case MSND_MIXER_MIC: /* mic pot control */ if (dev->type == msndClassic) return -EINVAL; /* scaled by IMIX in digital mix */ writeb(bLeft, dev->SMA + SMA_bMicPotPosLeft); writeb(bRight, dev->SMA + SMA_bMicPotPosRight); if (snd_msnd_send_word(dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0) snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); break; case MSND_MIXER_VOLUME: /* master volume */ writew(wLeft, dev->SMA + SMA_wCurrMastVolLeft); writew(wRight, dev->SMA + SMA_wCurrMastVolRight); /* fall through */ case MSND_MIXER_AUX: /* aux pot control */ /* scaled by master volume */ /* fall through */ /* digital controls */ case MSND_MIXER_SYNTH: /* synth vol (dsp mix) */ case MSND_MIXER_PCM: /* pcm vol (dsp mix) */ case MSND_MIXER_IMIX: /* input monitor (dsp mix) */ /* scaled by master volume */ updatemaster = 1; break; default: return -EINVAL; } if (updatemaster) { /* update master volume scaled controls */ update_volm(MSND_MIXER_PCM, wCurrPlayVol); update_volm(MSND_MIXER_IMIX, wCurrInVol); if (dev->type == msndPinnacle) update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol); update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS); } return 0; }