耳机输入设备注册(1)

这是基于8909平台代码跟踪。

硬件电路:在电源管理芯片PM8909上有个检测端口:HS_DET;

DTS配置:

/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";

			cdc-vdda-cp-supply = <&pm8909_s2>;
			qcom,cdc-vdda-cp-voltage = <1800000 2200000>;
			qcom,cdc-vdda-cp-current = <500000>;

			cdc-vdda-h-supply = <&pm8909_l5>;
			qcom,cdc-vdda-h-voltage = <1800000 1800000>;
			qcom,cdc-vdda-h-current = <10000>;

			cdc-vdd-px-supply = <&pm8909_l5>;
			qcom,cdc-vdd-px-voltage = <1800000 1800000>;
			qcom,cdc-vdd-px-current = <5000>;

			cdc-vdd-pa-supply = <&pm8909_s2>;
			qcom,cdc-vdd-pa-voltage = <1800000 2200000>;
			qcom,cdc-vdd-pa-current = <260000>;

			cdc-vdd-mic-bias-supply = <&pm8909_l13>;
			qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
			qcom,cdc-vdd-mic-bias-current = <5000>;

			qcom,cdc-mclk-clk-rate = <9600000>;

			qcom,cdc-static-supplies = "cdc-vdda-h",
						   "cdc-vdd-px",
						   "cdc-vdd-pa",
						   "cdc-vdda-cp";

			qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
		
其中的pm8909_conga_dig又是kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi中声卡配置的asoc-codec赋值,如下
  
  
		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";

			cdc-vdda-cp-supply = <&pm8909_s2>;
			qcom,cdc-vdda-cp-voltage = <1800000 2200000>;
			qcom,cdc-vdda-cp-current = <500000>;

			cdc-vdda-h-supply = <&pm8909_l5>;
			qcom,cdc-vdda-h-voltage = <1800000 1800000>;
			qcom,cdc-vdda-h-current = <10000>;

			cdc-vdd-px-supply = <&pm8909_l5>;
			qcom,cdc-vdd-px-voltage = <1800000 1800000>;
			qcom,cdc-vdd-px-current = <5000>;

			cdc-vdd-pa-supply = <&pm8909_s2>;
			qcom,cdc-vdd-pa-voltage = <1800000 2200000>;
			qcom,cdc-vdd-pa-current = <260000>;

			cdc-vdd-mic-bias-supply = <&pm8909_l13>;
			qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
			qcom,cdc-vdd-mic-bias-current = <5000>;

			qcom,cdc-mclk-clk-rate = <9600000>;

			qcom,cdc-static-supplies = "cdc-vdda-h",
						   "cdc-vdd-px",
						   "cdc-vdd-pa",
						   "cdc-vdda-cp";

			qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
		
代码执行:
在/kernel/sound/soc/codecs/msm8x16-wcd.c中的msm8x16_wcd_spmi_probe中注册了soc_codec_dev_msm8x16_wcd的codec driver.
再开机过程中调入soc_codec_dev_msm8x16_wcd的probe函数msm8x16_wcd_codec_probe,probe函数通过wcd_mbhc_init进行对mbhc的初始化。
在wcd_mbhc_init函数中
	if (mbhc->headset_jack.jack == NULL) {
		ret = snd_soc_jack_new(codec, "Headset Jack",
				WCD_MBHC_JACK_MASK, &mbhc->headset_jack);
		if (ret) {
			pr_err("%s: Failed to create new jack\n", __func__);
			return ret;
		}
注册一个新的后缀为"Headset Jack"的input设备;
snd_soc_jack_new中主要是调用了snd_jack_new函数,进行下一步的调用;

  
  
int snd_jack_new(struct snd_card *card, const char *id, int type,
		 struct snd_jack **jjack)
{
	struct snd_jack *jack;
	int err;
	int i;
	static struct snd_device_ops ops = {
		.dev_free = snd_jack_dev_free,
		.dev_register = snd_jack_dev_register,
	};

	jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
	if (jack == NULL)
		return -ENOMEM;

	jack->id = kstrdup(id, GFP_KERNEL);

	jack->input_dev = input_allocate_device();
	if (jack->input_dev == NULL) {
		err = -ENOMEM;
		goto fail_input;
	}

	jack->input_dev->phys = "ALSA";

	jack->type = type;

	for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++)
		if (type & (1 << i))
			input_set_capability(jack->input_dev, EV_SW,
					     jack_switch_types[i]);

	err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
	if (err < 0)
		goto fail_input;

	*jjack = jack;

	return 0;

fail_input:
	input_free_device(jack->input_dev);
	kfree(jack->id);
	kfree(jack);
	return err;
}
在这个函数中新建了snd_device_ops  ops并且调用了snd_device_new函数创建一个SNDRV_DEV_JACK设备。其中在snd_device_ops的snd_jack_dev_register函数中注册了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);
	jack->input_dev->name = jack->name;

	/* Default to the sound card device. */
	if (!jack->input_dev->dev.parent)
		jack->input_dev->dev.parent = snd_card_get_device_link(card);

	/* Add capabilities for any keys that are enabled */
	for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
		int testbit = SND_JACK_BTN_0 >> i;

		if (!(jack->type & testbit))
			continue;

		if (!jack->key[i])
			jack->key[i] = BTN_0 + i;

		input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
	}

	err = input_register_device(jack->input_dev);
	if (err == 0)
		jack->registered = 1;

	return err;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值