wm9712.rar

  • PUDN用户
    了解作者
  • Unix_Linux
    开发工具
  • 6KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 1
    下载次数
  • 2015-03-13 10:20
    上传日期
wm9712.c ALSA Soc WM9712 codec support.
wm9712.rar
  • wm9712.c
    24.8KB
  • wm9712.h
    156B
内容介绍
/* * wm9712.c -- ALSA Soc WM9712 codec support * * Copyright 2006-12 Wolfson Microelectronics PLC. * Author: Liam Girdwood <lrg@slimlogic.co.uk> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ #include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/ac97_codec.h> #include <sound/initval.h> #include <sound/soc.h> #include <sound/tlv.h> #include "wm9712.h" struct wm9712_priv { struct snd_ac97 *ac97; unsigned int hp_mixer[2]; struct mutex lock; }; static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg); static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val); /* * WM9712 register cache */ static const u16 wm9712_reg[] = { 0x6174, 0x8000, 0x8000, 0x8000, /* 6 */ 0x0f0f, 0xaaa0, 0xc008, 0x6808, /* e */ 0xe808, 0xaaa0, 0xad00, 0x8000, /* 16 */ 0xe808, 0x3000, 0x8000, 0x0000, /* 1e */ 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */ 0x0405, 0x0410, 0xbb80, 0xbb80, /* 2e */ 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */ 0x0000, 0x2000, 0x0000, 0x0000, /* 3e */ 0x0000, 0x0000, 0x0000, 0x0000, /* 46 */ 0x0000, 0x0000, 0xf83e, 0xffff, /* 4e */ 0x0000, 0x0000, 0x0000, 0xf83e, /* 56 */ 0x0008, 0x0000, 0x0000, 0x0000, /* 5e */ 0xb032, 0x3e00, 0x0000, 0x0000, /* 66 */ 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */ 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */ 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */ }; #define HPL_MIXER 0x0 #define HPR_MIXER 0x1 static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"}; static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"}; static const char *wm9712_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; static const char *wm9712_spk_src[] = {"Speaker Mix", "Headphone Mix"}; static const char *wm9712_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; static const char *wm9712_base[] = {"Linear Control", "Adaptive Boost"}; static const char *wm9712_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; static const char *wm9712_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer", "Line", "Headphone Mixer", "Phone Mixer", "Phone"}; static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; static const char *wm9712_diff_sel[] = {"Mic", "Line"}; static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0); static const struct soc_enum wm9712_enum[] = { SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), SOC_ENUM_SINGLE(AC97_AUX, 9, 4, wm9712_out3_src), SOC_ENUM_SINGLE(AC97_AUX, 8, 2, wm9712_spk_src), SOC_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9712_rec_adc), SOC_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9712_base), SOC_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9712_rec_gain), SOC_ENUM_SINGLE(AC97_MIC, 5, 4, wm9712_mic), SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9712_rec_sel), SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9712_rec_sel), SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9712_ng_type), SOC_ENUM_SINGLE(0x5c, 8, 2, wm9712_diff_sel), }; static const struct snd_kcontrol_new wm9712_snd_ac97_controls[] = { SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1), SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1), SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1), SOC_SINGLE("Speaker Playback ZC Switch", AC97_MASTER, 7, 1, 0), SOC_SINGLE("Speaker Playback Invert Switch", AC97_MASTER, 6, 1, 0), SOC_SINGLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 7, 1, 0), SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_MONO, 7, 1, 0), SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1), SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1), SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), SOC_ENUM("ALC Function", wm9712_enum[0]), SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), SOC_ENUM("ALC NG Type", wm9712_enum[10]), SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), SOC_SINGLE("Mic Headphone Volume", AC97_VIDEO, 12, 7, 1), SOC_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), SOC_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), SOC_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), SOC_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), SOC_SINGLE("PCBeep Bypass Headphone Volume", AC97_PC_BEEP, 12, 7, 1), SOC_SINGLE("PCBeep Bypass Speaker Volume", AC97_PC_BEEP, 8, 7, 1), SOC_SINGLE("PCBeep Bypass Phone Volume", AC97_PC_BEEP, 4, 7, 1), SOC_SINGLE("Aux Playback Headphone Volume", AC97_CD, 12, 7, 1), SOC_SINGLE("Aux Playback Speaker Volume", AC97_CD, 8, 7, 1), SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1), SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv), SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1, boost_tlv), SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), SOC_SINGLE("3D Playback Volume", AC97_3D_CONTROL, 0, 15, 0), SOC_ENUM("Bass Control", wm9712_enum[5]), SOC_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), SOC_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1), SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv), SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv), }; static const unsigned int wm9712_mixer_mute_regs[] = { AC97_VIDEO, AC97_PCM, AC97_LINE, AC97_PHONE, AC97_CD, AC97_PC_BEEP, }; /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); unsigned int val = ucontrol->value.enumerated.item[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mixer, mask, shift, old; struct snd_soc_dapm_update update; bool change; mixer = mc->shift >> 8; shift = mc->shift & 0xff; mask = 1 << shift; mutex_lock(&wm9712->lock); old = wm9712->hp_mixer[mixer]; if (ucontrol->value.enumerated.item[0]) wm9712->hp_mixer[mixer] |= mask; else wm9712->hp_mixer[mixer] &= ~mask; change = old != wm9712->hp_mixer[mixer]; if (change) { update.kcontrol = kcontrol; update.reg = wm9712_mixer_mute_regs[shift]; update.mask = 0x8000; if ((wm9712->hp_
评论
    相关推荐
    • SoC.rar
      SOC文件,小型的片上系统,能够实现20个左右的命令
    • soc.rar
      Fetch a unique (reclaimable) SOC ID.
    • soc.rar
      Miscellaneous SoC-specific hooks.
    • SoC-VaccineRefrigerator
      SoC疫苗冰箱 疫苗制冷机(VARE)项目已提交给都灵理工大学的片上系统架构20/21课程。 作者:Coralie Allioux,Gabriel Ganzer。 接种疫苗是预防疾病和挽救生命的一种安全有效的方法。 由于其成分,许多疫苗在制造...
    • soc gds viewer
      一个十分好的 windows下查看 soc gds文件的软件 我找了好久,最后找到特此跟大家分享。
    • 锂电池建模与EKF的SOC估计
      使用simulink建模的EKF估算SOC
    • 电池SOC模型
      电池SOC模型,是基础的模型,供大家下载交流学习
    • EKF估算SOC
      EKF估算SOC,自己做的资源,有需要的欢迎下载
    • 赛元魔盒1.3 SOC Code Generator v1.3.rar
      赛元魔盒1.3 SOC Code Generator v1.3.rar 赛元魔盒1.3 SOC Code Generator v1.3.rar赛元魔盒1.3 SOC Code Generator v1.3.rar
    • libsystemctlm-soc.zip
      lisystemclm-soc testing