//-------------------------------------------------------------------------------------------------------------
硬件:
PM-8909管腳HS_DET (J12)
//-------------------------------------------------------------------------------------------------------------
./arch/arm/boot/dts/qcom/msm-pm8909.dtsi
&spmi_bus {
qcom,pm8909@1 {
...
pm8909_conga_dig: 8909_wcd_codec@f000 {
compatible = "qcom,msm8x16_wcd_codec";
reg = <0xf000 0x100>;
interrupt-parent = <&spmi_bus>;
interrupts = <0x1 0xf0 0x0>,
<0x1 0xf0 0x1>,
<0x1 0xf0 0x2>,
<0x1 0xf0 0x3>,
<0x1 0xf0 0x4>,
<0x1 0xf0 0x5>,
<0x1 0xf0 0x6>,
<0x1 0xf0 0x7>;
interrupt-names = "spk_cnp_int",
"spk_clip_int",
"spk_ocp_int",
"ins_rem_det1", //中斷
"but_rel_det",
"but_press_det",
"ins_rem_det",
"mbhc_int";
...
};
...
};
//-------------------------------------------------------------------------------------------------------------
kernel/sound/soc/codecs/msm8x16-wcd.c
static struct of_device_id msm8x16_wcd_spmi_of_match[] = {
{ .compatible = "qcom,msm8x16_wcd_codec",},
{ },
};
static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi)
{
...
ret = snd_soc_register_codec(&spmi->dev, &soc_codec_dev_msm8x16_wcd, //註冊
msm8x16_wcd_i2s_dai,
ARRAY_SIZE(msm8x16_wcd_i2s_dai));
...
}
static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = {
.probe = msm8x16_wcd_codec_probe, //開機時進入此函數
.remove = msm8x16_wcd_codec_remove,
};
static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
{
...
wcd_mbhc_init(&msm8x16_wcd_priv->mbhc, codec, &mbhc_cb, &intr_ids, //執行函數,最後實現input的註冊
true);
...
}
//-------------------------------------------------------------------------------------------------------------
kernel/sound/soc/codecs/wcd-mbhc-v2.c
int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
const struct wcd_mbhc_cb *mbhc_cb,
const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
bool impedance_det_en)
{
...
if (mbhc->headset_jack.jack == NULL) {
ret = snd_soc_jack_new(codec, "Headset Jack", //"Headset Jack"是注冊的input設備名字後綴
WCD_MBHC_JACK_MASK, &mbhc->headset_jack);
...
}
//-------------------------------------------------------------------------------------------------------------
kernel/sound/soc/soc-jack.c
int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
struct snd_soc_jack *jack)
{
...
return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
}
//-------------------------------------------------------------------------------------------------------------
kernel/sound/core/jack.c
int snd_jack_new(struct snd_card *card, const char *id, int type,
struct snd_jack **jjack)
{
...
static struct snd_device_ops ops = {
.dev_free = snd_jack_dev_free,
.dev_register = snd_jack_dev_register,
};
...
err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); //xcz
if (err < 0)
goto fail_input;
...
}
static int snd_jack_dev_register(struct snd_device *device)
{
struct snd_jack *jack = device->device_data;
struct snd_card *card = device->card;
int err, i;
snprintf(jack->name, sizeof(jack->name), "%s %s",
card->shortname, jack->id); //註冊的input設備最終顯示名稱
jack->input_dev->name = jack->name;
...
err = input_register_device(jack->input_dev); //最終註冊input設備
if (err == 0)
jack->registered = 1;
return err;
}