高通MSM8953 Android7.1蓝牙接电话流程(App到Adsp)

1.packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
private final AudioManager mAudioManager;
private void acceptCall(int flag, boolean retry)
{
  if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
            Log.d(TAG,"hfp_enable=true");
            mAudioManager.setParameters("hfp_enable=true");
        }
}

private void processAudioEvent(int state, BluetoothDevice device) 
{
  switch (state) {
    case HeadsetClientHalConstants.AUDIO_STATE_CONNECTED:
         mAudioManager.setParameters("hfp_set_sampling_rate=16000");
         mAudioManager.setParameters("hfp_enable=true");
         mAudioManager.setParameters("hfp_volume=" + hfVol);
         transitionTo(mAudioOn);
  }
}

2.frameworks/base/media/java/android/media/AudioManager.java
 public void setParameters(String keyValuePairs) 
 {
        AudioSystem.setParameters(keyValuePairs);
 }
 
 
3.frameworks/base/media/java/android/media/AudioSystem.java
public static native int setParameters(String keyValuePairs);

4.frameworks/base/core/jni/android_media_AudioSystem.cpp
static jint
android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
{
 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
}


5.frameworks/av/media/libmedia/AudioSystem.cpp
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
    const sp& af = AudioSystem::get_audio_flinger();
    return af->setParameters(ioHandle, keyValuePairs);
}

6.frameworks/av/services/audioflinger/AudioFlinger.cpp
status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs){
  audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice
  ALOGE("xxx---> %s(), line = %d, devices[%zu] = %s, dev = %p,dev->common.module->name = %s",__FUNCTION__,__LINE__,i,keyValuePairs.string(),dev,dev->common.module->name);
  result = dev->set_parameters(dev, keyValuePairs.string());
}

7.hardware/qcom/audio/hal/audio_hw.c
static int adev_open_output_stream()
{
  out->stream.common.set_parameters = out_set_parameters;
}

static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
   audio_extn_set_parameters(adev, parms);
}

8.hardware/qcom/audio/hal/audio_extn/audio_extn.c
void audio_extn_set_parameters(struct audio_device *adev,struct str_parms *parms)
{
 audio_extn_set_anc_parameters(adev, parms);
}

9.void audio_extn_set_anc_parameters(struct audio_device *adev, struct str_parms *parms)
{
  platform_set_parameters(adev->platform, reply_44_1);
}

10.hardware/qcom/audio/hal/msm8916/platform.c
int platform_set_parameters(void *platform, struct str_parms *parms)
{
   ret = set_hd_voice(my_data, state);
}

static int set_hd_voice(struct platform_data *my_data, bool state)
{
  ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
  ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
}

11.external/tinyalsa/mixer.c
int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
{
   return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
}

12.kernel/msm-3.18/sound/core/control.c
static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
  case SNDRV_CTL_IOCTL_ELEM_WRITE:
       return snd_ctl_elem_write_user(ctl, argp);
}

static int snd_ctl_elem_write_user(struct snd_ctl_file *file, struct snd_ctl_elem_value __user *_control)
{        
    result = snd_ctl_elem_write(card, file, control);
    copy_to_user(_control, control, sizeof(*control));
    return result;
}

//snd_kcontrol结构体分析
struct snd_kcontrol 
{
  snd_kcontrol_get_t *get;//读Adsp寄存器
  snd_kcontrol_put_t *put;//写Adsp寄存器
}
typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);

//注册put()和get()回调函数
static int snd_ctl_elem_add()
{
 if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
 kctl.info = snd_ctl_elem_user_enum_info;                          else                                                                                                                                                                      kctl.info = snd_ctl_elem_user_info;//获取Adsp信息
if (access & SNDRV_CTL_ELEM_ACCESS_READ)
	kctl.get = snd_ctl_elem_user_get;//注册回调,读Adsp寄存器
if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
	kctl.put = snd_ctl_elem_user_put;//注册回调,写Adsp寄存器
}


struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, void *private_data)
{
  kctl.info = ncontrol->info;
  kctl.get = ncontrol->get;
  kctl.put = ncontrol->put;//这里是从Adsp传过来回调函数
  kctl.tlv.p = ncontrol->tlv.p;
  kctl.private_value = ncontrol->private_value;
  kctl.private_data = private_data;
  return snd_ctl_new(&kctl, access);
}
}

static int snd_ctl_elem_write()
{
  struct snd_kcontrol *kctl;
  result = kctl->put(kctl, control); //这里即是调用snd_ctl_elem_user_put()函数
}

kernel/msm-3.18/include/sound/soc.h
#define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \
{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
        .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
        .put = snd_soc_put_volsw_range, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
                {.reg = xreg, .rreg = xreg, .shift = xshift, \
                 .rshift = xshift,  .min = xmin, .max = xmax, \
                 .platform_max = xmax, .invert = xinvert} }
#define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
                 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
        .tlv.p = (tlv_array), \
        .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
        .put = snd_soc_put_volsw, \ //snd_soc_put_volsw();回调函数
        .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
		

13.kernel/msm-3.18/sound/soc/soc-core.c
int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
{
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        unsigned int shift = mc->shift;
        unsigned int rshift = mc->rshift;
		
		err = snd_soc_component_update_bits(component, reg, val_mask, val);
}		

14.kernel/msm-3.18/sound/soc/soc-io.c
static int snd_soc_component_update_bits_legacy(
        struct snd_soc_component *component, unsigned int reg,
        unsigned int mask, unsigned int val, bool *change)
{
  component->write(component, reg, new);//相当于回调了snd_codec_write();写寄存器
}

kernel/msm-3.18/include/sound/soc.h
struct snd_soc_component {
        const char *name;
        int id;
        const char *name_prefix;
        struct device *dev;
		int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
}

15.kernel/msm-3.18/sound/soc/soc-core.c
int snd_soc_register_codec(struct device *dev,
                           const struct snd_soc_codec_driver *codec_drv,
                           struct snd_soc_dai_driver *dai_drv,
                           int num_dai)
{
   codec->component.write = snd_soc_codec_drv_write;						   
}

static int snd_soc_codec_drv_write(struct snd_soc_component *component,
        unsigned int reg, unsigned int val)
{
        struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
        return codec->driver->write(codec, reg, val);//这里调用的snd_soc_component结构体里的write()
}
<1>.struct snd_soc_codec {
  const struct snd_soc_codec_driver *driver;
  struct snd_soc_component component;
}
<2>./* codec driver */ codec的write()函数
struct snd_soc_codec_driver {
   int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
};

//根据平台不同,会调用到当前平台所用的codec,本平台为msm8953用的codec为msm8x16-wcd
kernel/msm-3.18/sound/soc/codecs/msm8x16-wcd.c
static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = {
  .write = msm8x16_wcd_write,
}

static int msm8x16_wcd_write(struct snd_soc_codec *codec, unsigned int reg,
                             unsigned int value)
{
        int ret;
        struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
        BUG_ON(reg > MSM8X16_WCD_MAX_REGISTER);
        return __msm8x16_wcd_reg_write(codec, reg, (u8)value);
}

static int __msm8x16_wcd_reg_write(struct snd_soc_codec *codec,
                        unsigned short reg, u8 val)
{
  ret = msm8x16_wcd_ahb_write_device(msm8x16_wcd, reg, &val, 1);
}


static int msm8x16_wcd_ahb_write_device(struct msm8x16_wcd *msm8x16_wcd,
                                        u16 reg, u8 *value, u32 bytes)
{
        u32 temp = ((u32)(*value)) & 0x000000FF;
        u16 offset = (reg - 0x0200) & 0x03FF;
        bool q6_state = false;
        q6_state = q6core_is_adsp_ready();
        pr_debug("%s: DSP is ready %d\n", __func__, q6_state);
        iowrite32(temp, msm8x16_wcd->dig_base + offset);//写入到Adsp寄存器
        return 0;
}



 

你可能感兴趣的:(USB,Audio)