Linux ALSA驱动基本框架

ADAU1701

  • dt
i2c_bus {
	adau1701@34 {
		compatible = "adi,adau1701";
		reg = <0x34>;
		reset-gpio = <&gpio 23 0>;
		avdd-supply = <&vdd_3v3_reg>;
		dvdd-supply = <&vdd_3v3_reg>;
		adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
                                           0x4 0x4 0x4 0x4 0x4 0x4>;
	};
};
  • drv code
static const struct snd_soc_dai_ops adau1701_dai_ops = {
	.set_fmt	= adau1701_set_dai_fmt,
	.hw_params	= adau1701_hw_params,
	.digital_mute	= adau1701_digital_mute,
	.startup	= adau1701_startup,
};

static struct snd_soc_dai_driver adau1701_dai = {
	.name = "adau1701",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 8,
		.rates = ADAU1701_RATES,
		.formats = ADAU1701_FORMATS,
	},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 2,
		.channels_max = 8,
		.rates = ADAU1701_RATES,
		.formats = ADAU1701_FORMATS,
	},
	.ops = &adau1701_dai_ops,
	.symmetric_rates = 1,
};

static struct snd_soc_codec_driver adau1701_codec_drv = {
	.probe			= adau1701_probe,
	.remove			= adau1701_remove,
	.resume			= adau1701_resume,
	.suspend		= adau1701_suspend,
	.set_bias_level		= adau1701_set_bias_level,
	.idle_bias_off		= true,

	.controls		= adau1701_controls,
	.num_controls		= ARRAY_SIZE(adau1701_controls),
	.dapm_widgets		= adau1701_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(adau1701_dapm_widgets),
	.dapm_routes		= adau1701_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(adau1701_dapm_routes),

	.set_sysclk		= adau1701_set_sysclk,
};

static int adau1701_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	//...........
	
	ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, &adau1701_dai, 1);
	return ret;
}

static const struct i2c_device_id adau1701_i2c_id[] = {
	{ "adau1701", 0 },
	{ "adau1702", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);

static struct i2c_driver adau1701_i2c_driver = {
	.driver = {
		.name	= "adau1701",
		.of_match_table	= of_match_ptr(adau1701_dt_ids),
	},
	.probe		= adau1701_i2c_probe,
	.remove		= adau1701_i2c_remove,
	.id_table	= adau1701_i2c_id,
};
module_i2c_driver(adau1701_i2c_driver);

AIC32x4

  • dt
aic32x4-sound {			//machine 匹配层的驱动节点。
	status = "okay";	//默认打开
	compatible = "simple-audio-card";	//simple-card framework框架
	simple-audio-card,format = "i2s";
	simple-audio-card,name = "rockchip,aic32x4";	
	simple-audio-card,bitclock-master = <&codec_aic32x4>;
	simple-audio-card,frame-master = <&codec_aic32x4>;		


	simple-audio-card,cpu {
		sound-dai = <&i2s_2ch_0>;	//指定cpu接入音频编解码的dai(数字化接口)
	};
	simple-audio-card,codec {
		sound-dai = <&codec_aic32x4>;	//指定编解码音频接入cpu的dai(数字化接口)
	};
};

&i2s_2ch_0 {
	status = "okay";	//默认打开
	#sound-dai-cells = <0>;
	rockchip,bclk-fs = <32>;
	rockchip,clk-trcm = <1>;
	rockchip,playback-channels = <2>;
	rockchip,capture-channels = <2>;
	assigned-clocks = <&cru SCLK_I2S0_2CH_OUT>;
	assigned-clock-rates = <12000000>;
};

&i2c2 {
	clock-frequency = <400000>;
	status = "okay";
	
	codec_aic32x4: tlv320aic32x4@55 {
		#sound-dai-cells = <0>;
		compatible = "ti,tlv320aic32x4";
		reg = <0x55>;
		system-clock-frequency = <12000000>;
		clocks = <&cru SCLK_I2S0_2CH_OUT>;
		clock-names = "mclk";
		//pinctrl-names = "default";
		//pinctrl-0 = <&i2s_2ch_0_mclk>;
		reset-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_LOW>;
	};	
}

  • drv code
static const struct file_operations proc_aic32x4_reg_ops = {
	.write		= aic32x4_reg_write,
	.read		= aic32x4_reg_read,
};

static const struct file_operations proc_aic32x4_filter_ops = {
	.write		= aic32x4_filter_write,
};

static int aic32x4_probe(struct snd_soc_codec *codec)
{
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	
	aic32x4_init(codec);
	udelay(100);
	
	aic32x4_agc_param_init(codec);
	aic32x4_agc_enable_set(codec, 1);
	
	aic32x4_filter_freq_init(codec,FILTER_MODE_BOTH, FILTER_FRE_220, FILTER_FRE_15000);
	aic32x4_filter_enable_set(codec,FILTER_MODE_BOTH,0);
	
	g_aic32x4_codec = codec;
	proc_aic32x4_reg = proc_create("aic32x4_reg", 0644, NULL, &proc_aic32x4_reg_ops);
	proc_aic32x4_filter = proc_create("aic32x4_filter", 0644, NULL, &proc_aic32x4_filter_ops);
	return 0;
}

static const struct snd_soc_dai_ops aic32x4_ops = {
	.hw_params = aic32x4_hw_params,
	.digital_mute = aic32x4_mute,
	.set_fmt = aic32x4_set_dai_fmt,
	.set_sysclk = aic32x4_set_dai_sysclk,
};

static struct snd_soc_dai_driver aic32x4_dai = {
	.name = "tlv320aic32x4-hifi",
	.playback = {
		     .stream_name = "Playback",
		     .channels_min = 1,
		     .channels_max = 2,
		     .rates = AIC32X4_RATES,
		     .formats = AIC32X4_FORMATS,},
	.capture = {
		    .stream_name = "Capture",
		    .channels_min = 1,
		    .channels_max = 2,
		    .rates = AIC32X4_RATES,
		    .formats = AIC32X4_FORMATS,},
	.ops = &aic32x4_ops,
	.symmetric_rates = 1,
};

static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
	.probe = aic32x4_probe,
	.set_bias_level = aic32x4_set_bias_level,
	.suspend_bias_off = true,

	.controls = aic32x4_snd_controls,
	.num_controls = ARRAY_SIZE(aic32x4_snd_controls),
	.dapm_widgets = aic32x4_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
	.dapm_routes = aic32x4_dapm_routes,
	.num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
};

static int aic32x4_i2c_probe(struct i2c_client *i2c,
			     const struct i2c_device_id *id)
{
	//......
	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
	return;
}

static const struct i2c_device_id aic32x4_i2c_id[] = {
	{ "tlv320aic32x4", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);

static const struct of_device_id aic32x4_of_id[] = {
	{ .compatible = "ti,tlv320aic32x4", },
	{ /* senitel */ }
};
MODULE_DEVICE_TABLE(of, aic32x4_of_id);

static struct i2c_driver aic32x4_i2c_driver = {
	.driver = {
		.name = "tlv320aic32x4",
		.owner = THIS_MODULE,
		.of_match_table = aic32x4_of_id,
	},
	.probe =    aic32x4_i2c_probe,
	.remove =   aic32x4_i2c_remove,
	.id_table = aic32x4_i2c_id,
};

module_i2c_driver(aic32x4_i2c_driver);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值