ls_stk3332.c
时间: 2024-03-13 07:47:10 浏览: 186
以下是一个示例的ls_stk3332.c驱动程序,用于实现RK3588与STK3332之间的音频输入和输出功能:
```
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/control.h>
#define STK3332_REG_GAIN 0x00
#define STK3332_REG_VOLUME 0x01
#define STK3332_REG_MUTE 0x02
struct stk3332_data {
struct regmap *regmap;
unsigned int gain;
unsigned int volume;
bool mute;
};
static int stk3332_set_gain(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
unsigned int gain = ucontrol->value.integer.value[0];
if (gain > 255)
gain = 255;
data->gain = gain;
regmap_write(data->regmap, STK3332_REG_GAIN, gain);
return 0;
}
static int stk3332_get_gain(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = data->gain;
return 0;
}
static int stk3332_set_volume(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
unsigned int volume = ucontrol->value.integer.value[0];
if (volume > 255)
volume = 255;
data->volume = volume;
regmap_write(data->regmap, STK3332_REG_VOLUME, volume);
return 0;
}
static int stk3332_get_volume(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = data->volume;
return 0;
}
static int stk3332_set_mute(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
bool mute = ucontrol->value.integer.value[0];
data->mute = mute;
regmap_write(data->regmap, STK3332_REG_MUTE, mute ? 1 : 0);
return 0;
}
static int stk3332_get_mute(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct stk3332_data *data = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = data->mute ? 1 : 0;
return 0;
}
static const struct snd_kcontrol_new stk3332_controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Gain",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = snd_ctl_boolean_mono_info,
.get = stk3332_get_gain,
.put = stk3332_set_gain,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Volume",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = snd_ctl_boolean_mono_info,
.get = stk3332_get_volume,
.put = stk3332_set_volume,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Mute",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = snd_ctl_boolean_mono_info,
.get = stk3332_get_mute,
.put = stk3332_set_mute,
},
{ } /* end */
};
static int stk3332_pcm_open(struct snd_pcm_substream *substream)
{
return 0;
}
static int stk3332_pcm_close(struct snd_pcm_substream *substream)
{
return 0;
}
static int stk3332_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
return 0;
}
static int stk3332_pcm_hw_free(struct snd_pcm_substream *substream)
{
return 0;
}
static struct snd_pcm_ops stk3332_pcm_ops = {
.open = stk3332_pcm_open,
.close = stk3332_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = stk3332_pcm_hw_params,
.hw_free = stk3332_pcm_hw_free,
};
static int stk3332_pcm_new(struct snd_card *card,
struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm;
int ret;
ret = snd_pcm_new(card, "STK3332 PCM", 0, 1, 0, &pcm);
if (ret < 0)
return ret;
pcm->private_data = rtd;
pcm->info_flags = 0;
strcpy(pcm->name, "STK3332 PCM");
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &stk3332_pcm_ops);
return 0;
}
static int stk3332_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct stk3332_data *data;
struct regmap *regmap;
regmap = dev_get_regmap(dev->parent, NULL);
if (!regmap) {
dev_err(dev, "Failed to get regmap\n");
return -ENODEV;
}
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->regmap = regmap;
data->gain = 128;
data->volume = 128;
data->mute = false;
platform_set_drvdata(pdev, data);
// 注册音频控制器
snd_soc_register_codec(&pdev->dev, &codec_stk3332, &stk3332_dai, 1);
// 注册PCM设备
return snd_soc_new_pcm_runtime(&pdev->dev, &stk3332_pcm_dai, &stk3332_pcm_platform, 0);
}
static int stk3332_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static const struct of_device_id stk3332_of_match[] = {
{ .compatible = "st,stk3332", },
{ },
};
MODULE_DEVICE_TABLE(of, stk3332_of_match);
static struct platform_driver stk3332_driver = {
.probe = stk3332_probe,
.remove = stk3332_remove,
.driver = {
.name = "stk3332",
.of_match_table = stk3332_of_match,
},
};
module_platform_driver(stk3332_driver);
MODULE_DESCRIPTION("STK3332 audio driver");
MODULE_AUTHOR("Your Name");
MODULE_LICENSE("GPL");
```
以上驱动程序仅供参考,具体的驱动程序要根据实际的硬件连接和应用需求进行调整和修改。同时,需要根据实际情况进行dts配置和驱动程序的加载,以实现音频输入和输出的功能。
阅读全文