brintos

brintos / linux-shallow public Read only

0
0
Text · 5.0 KiB · 1826a4d Raw
178 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Sound card driver for Intel Haswell Lynx Point with Realtek 56404 *5 * Copyright (C) 2013, Intel Corporation6 */7 8#include <linux/module.h>9#include <linux/platform_device.h>10#include <sound/core.h>11#include <sound/pcm.h>12#include <sound/pcm_params.h>13#include <sound/soc.h>14#include <sound/soc-acpi.h>15#include "../../codecs/rt5640.h"16 17static const struct snd_soc_dapm_widget card_widgets[] = {18	SND_SOC_DAPM_HP("Headphones", NULL),19	SND_SOC_DAPM_MIC("Mic", NULL),20};21 22static const struct snd_soc_dapm_route card_routes[] = {23	{"Headphones", NULL, "HPOR"},24	{"Headphones", NULL, "HPOL"},25	{"IN2P", NULL, "Mic"},26 27	/* CODEC BE connections */28	{"SSP0 CODEC IN", NULL, "AIF1 Capture"},29	{"AIF1 Playback", NULL, "SSP0 CODEC OUT"},30};31 32static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,33				      struct snd_pcm_hw_params *params)34{35	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);36	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);37 38	/* The ADSP will convert the FE rate to 48k, stereo. */39	rate->min = rate->max = 48000;40	channels->min = channels->max = 2;41	/* Set SSP0 to 16 bit. */42	params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);43 44	return 0;45}46 47static int codec_link_hw_params(struct snd_pcm_substream *substream,48				struct snd_pcm_hw_params *params)49{50	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);51	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);52	int ret;53 54	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, SND_SOC_CLOCK_IN);55	if (ret < 0) {56		dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret);57		return ret;58	}59 60	/* Set correct codec filter for DAI format and clock config. */61	snd_soc_component_update_bits(codec_dai->component, 0x83, 0xffff, 0x8000);62 63	return ret;64}65 66static const struct snd_soc_ops codec_link_ops = {67	.hw_params = codec_link_hw_params,68};69 70SND_SOC_DAILINK_DEF(system, DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));71SND_SOC_DAILINK_DEF(offload0, DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin")));72SND_SOC_DAILINK_DEF(offload1, DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin")));73SND_SOC_DAILINK_DEF(loopback, DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin")));74 75SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));76SND_SOC_DAILINK_DEF(codec, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT33CA:00", "rt5640-aif1")));77SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));78SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));79 80static struct snd_soc_dai_link card_dai_links[] = {81	/* Front End DAI links */82	{83		.name = "System",84		.stream_name = "System Playback/Capture",85		.nonatomic = 1,86		.dynamic = 1,87		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},88		.dpcm_playback = 1,89		.dpcm_capture = 1,90		SND_SOC_DAILINK_REG(system, dummy, platform),91	},92	{93		.name = "Offload0",94		.stream_name = "Offload0 Playback",95		.nonatomic = 1,96		.dynamic = 1,97		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},98		.dpcm_playback = 1,99		SND_SOC_DAILINK_REG(offload0, dummy, platform),100	},101	{102		.name = "Offload1",103		.stream_name = "Offload1 Playback",104		.nonatomic = 1,105		.dynamic = 1,106		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},107		.dpcm_playback = 1,108		SND_SOC_DAILINK_REG(offload1, dummy, platform),109	},110	{111		.name = "Loopback",112		.stream_name = "Loopback",113		.nonatomic = 1,114		.dynamic = 1,115		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},116		.dpcm_capture = 1,117		SND_SOC_DAILINK_REG(loopback, dummy, platform),118	},119	/* Back End DAI links */120	{121		/* SSP0 - Codec */122		.name = "Codec",123		.id = 0,124		.nonatomic = 1,125		.no_pcm = 1,126		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC,127		.ignore_pmdown_time = 1,128		.be_hw_params_fixup = codec_link_hw_params_fixup,129		.ops = &codec_link_ops,130		.dpcm_playback = 1,131		.dpcm_capture = 1,132		SND_SOC_DAILINK_REG(ssp0_port, codec, platform),133	},134};135 136static struct snd_soc_card hsw_rt5640_card = {137	.name = "haswell-rt5640",138	.owner = THIS_MODULE,139	.dai_link = card_dai_links,140	.num_links = ARRAY_SIZE(card_dai_links),141	.dapm_widgets = card_widgets,142	.num_dapm_widgets = ARRAY_SIZE(card_widgets),143	.dapm_routes = card_routes,144	.num_dapm_routes = ARRAY_SIZE(card_routes),145	.fully_routed = true,146};147 148static int hsw_rt5640_probe(struct platform_device *pdev)149{150	struct snd_soc_acpi_mach *mach;151	struct device *dev = &pdev->dev;152	int ret;153 154	hsw_rt5640_card.dev = dev;155	mach = dev_get_platdata(dev);156 157	ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, mach->mach_params.platform);158	if (ret)159		return ret;160 161	return devm_snd_soc_register_card(dev, &hsw_rt5640_card);162}163 164static struct platform_driver hsw_rt5640_driver = {165	.probe = hsw_rt5640_probe,166	.driver = {167		.name = "hsw_rt5640",168		.pm = &snd_soc_pm_ops,169	},170};171 172module_platform_driver(hsw_rt5640_driver)173 174MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");175MODULE_DESCRIPTION("Sound card driver for Intel Haswell Lynx Point with Realtek 5640");176MODULE_LICENSE("GPL");177MODULE_ALIAS("platform:hsw_rt5640");178