]>
Commit | Line | Data |
---|---|---|
2025cf9e | 1 | // SPDX-License-Identifier: GPL-2.0-only |
9b351d46 JN |
2 | /* |
3 | * Intel Baytrail SST MAX98090 machine driver | |
4 | * Copyright (c) 2014, Intel Corporation. | |
9b351d46 JN |
5 | */ |
6 | ||
7 | #include <linux/init.h> | |
8 | #include <linux/module.h> | |
9 | #include <linux/platform_device.h> | |
10 | #include <linux/acpi.h> | |
11 | #include <linux/device.h> | |
12 | #include <linux/gpio.h> | |
13 | #include <linux/gpio/consumer.h> | |
14 | #include <linux/slab.h> | |
15 | #include <sound/pcm.h> | |
16 | #include <sound/pcm_params.h> | |
17 | #include <sound/soc.h> | |
18 | #include <sound/jack.h> | |
e56c72d5 | 19 | #include "../../codecs/max98090.h" |
9b351d46 JN |
20 | |
21 | struct byt_max98090_private { | |
22 | struct snd_soc_jack jack; | |
23 | }; | |
24 | ||
25 | static const struct snd_soc_dapm_widget byt_max98090_widgets[] = { | |
26 | SND_SOC_DAPM_HP("Headphone", NULL), | |
27 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | |
28 | SND_SOC_DAPM_MIC("Int Mic", NULL), | |
29 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | |
30 | }; | |
31 | ||
32 | static const struct snd_soc_dapm_route byt_max98090_audio_map[] = { | |
33 | {"IN34", NULL, "Headset Mic"}, | |
a5b37bf3 | 34 | {"Headset Mic", NULL, "MICBIAS"}, |
9b351d46 JN |
35 | {"DMICL", NULL, "Int Mic"}, |
36 | {"Headphone", NULL, "HPL"}, | |
37 | {"Headphone", NULL, "HPR"}, | |
38 | {"Ext Spk", NULL, "SPKL"}, | |
39 | {"Ext Spk", NULL, "SPKR"}, | |
40 | }; | |
41 | ||
42 | static const struct snd_kcontrol_new byt_max98090_controls[] = { | |
43 | SOC_DAPM_PIN_SWITCH("Headphone"), | |
44 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | |
45 | SOC_DAPM_PIN_SWITCH("Int Mic"), | |
46 | SOC_DAPM_PIN_SWITCH("Ext Spk"), | |
47 | }; | |
48 | ||
49 | static struct snd_soc_jack_pin hs_jack_pins[] = { | |
50 | { | |
51 | .pin = "Headphone", | |
52 | .mask = SND_JACK_HEADPHONE, | |
53 | }, | |
54 | { | |
55 | .pin = "Headset Mic", | |
56 | .mask = SND_JACK_MICROPHONE, | |
57 | }, | |
9b351d46 JN |
58 | }; |
59 | ||
60 | static struct snd_soc_jack_gpio hs_jack_gpios[] = { | |
61 | { | |
7c197881 | 62 | .name = "hp", |
9b351d46 JN |
63 | .report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, |
64 | .debounce_time = 200, | |
65 | }, | |
66 | { | |
7c197881 | 67 | .name = "mic", |
725a6dfd | 68 | .invert = 1, |
6a0cdcca | 69 | .report = SND_JACK_MICROPHONE, |
9b351d46 JN |
70 | .debounce_time = 200, |
71 | }, | |
72 | }; | |
73 | ||
7c197881 AS |
74 | static const struct acpi_gpio_params hp_gpios = { 0, 0, false }; |
75 | static const struct acpi_gpio_params mic_gpios = { 1, 0, false }; | |
76 | ||
77 | static const struct acpi_gpio_mapping acpi_byt_max98090_gpios[] = { | |
78 | { "hp-gpios", &hp_gpios, 1 }, | |
79 | { "mic-gpios", &mic_gpios, 1 }, | |
80 | {}, | |
81 | }; | |
82 | ||
9b351d46 JN |
83 | static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) |
84 | { | |
85 | int ret; | |
9b351d46 JN |
86 | struct snd_soc_card *card = runtime->card; |
87 | struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card); | |
88 | struct snd_soc_jack *jack = &drv->jack; | |
89 | ||
90 | card->dapm.idle_bias_off = true; | |
91 | ||
92 | ret = snd_soc_dai_set_sysclk(runtime->codec_dai, | |
93 | M98090_REG_SYSTEM_CLOCK, | |
94 | 25000000, SND_SOC_CLOCK_IN); | |
95 | if (ret < 0) { | |
96 | dev_err(card->dev, "Can't set codec clock %d\n", ret); | |
97 | return ret; | |
98 | } | |
99 | ||
100 | /* Enable jack detection */ | |
e0f7dd9d LPC |
101 | ret = snd_soc_card_jack_new(runtime->card, "Headset", |
102 | SND_JACK_LINEOUT | SND_JACK_HEADSET, jack, | |
103 | hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); | |
9b351d46 JN |
104 | if (ret) |
105 | return ret; | |
106 | ||
ab6f7d0d JN |
107 | return snd_soc_jack_add_gpiods(card->dev->parent, jack, |
108 | ARRAY_SIZE(hs_jack_gpios), | |
109 | hs_jack_gpios); | |
9b351d46 JN |
110 | } |
111 | ||
112 | static struct snd_soc_dai_link byt_max98090_dais[] = { | |
113 | { | |
114 | .name = "Baytrail Audio", | |
115 | .stream_name = "Audio", | |
116 | .cpu_dai_name = "baytrail-pcm-audio", | |
117 | .codec_dai_name = "HiFi", | |
118 | .codec_name = "i2c-193C9890:00", | |
119 | .platform_name = "baytrail-pcm-audio", | |
120 | .init = byt_max98090_init, | |
121 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | |
122 | SND_SOC_DAIFMT_CBS_CFS, | |
123 | }, | |
124 | }; | |
125 | ||
126 | static struct snd_soc_card byt_max98090_card = { | |
127 | .name = "byt-max98090", | |
54d8697f | 128 | .owner = THIS_MODULE, |
9b351d46 JN |
129 | .dai_link = byt_max98090_dais, |
130 | .num_links = ARRAY_SIZE(byt_max98090_dais), | |
131 | .dapm_widgets = byt_max98090_widgets, | |
132 | .num_dapm_widgets = ARRAY_SIZE(byt_max98090_widgets), | |
133 | .dapm_routes = byt_max98090_audio_map, | |
134 | .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map), | |
135 | .controls = byt_max98090_controls, | |
136 | .num_controls = ARRAY_SIZE(byt_max98090_controls), | |
969168e2 | 137 | .fully_routed = true, |
9b351d46 JN |
138 | }; |
139 | ||
140 | static int byt_max98090_probe(struct platform_device *pdev) | |
141 | { | |
7c197881 | 142 | struct device *dev = &pdev->dev; |
9b351d46 | 143 | struct byt_max98090_private *priv; |
7c197881 | 144 | int ret_val; |
9b351d46 | 145 | |
ffa481cf | 146 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
9b351d46 JN |
147 | if (!priv) { |
148 | dev_err(&pdev->dev, "allocation failed\n"); | |
149 | return -ENOMEM; | |
150 | } | |
151 | ||
7c197881 AS |
152 | ret_val = devm_acpi_dev_add_driver_gpios(dev->parent, acpi_byt_max98090_gpios); |
153 | if (ret_val) | |
154 | dev_dbg(dev, "Unable to add GPIO mapping table\n"); | |
155 | ||
9b351d46 JN |
156 | byt_max98090_card.dev = &pdev->dev; |
157 | snd_soc_card_set_drvdata(&byt_max98090_card, priv); | |
158 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_max98090_card); | |
159 | if (ret_val) { | |
160 | dev_err(&pdev->dev, | |
161 | "snd_soc_register_card failed %d\n", ret_val); | |
162 | return ret_val; | |
163 | } | |
164 | ||
7c197881 | 165 | return 0; |
9b351d46 JN |
166 | } |
167 | ||
9b351d46 JN |
168 | static struct platform_driver byt_max98090_driver = { |
169 | .probe = byt_max98090_probe, | |
9b351d46 JN |
170 | .driver = { |
171 | .name = "byt-max98090", | |
9b351d46 JN |
172 | .pm = &snd_soc_pm_ops, |
173 | }, | |
174 | }; | |
175 | module_platform_driver(byt_max98090_driver) | |
176 | ||
177 | MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver"); | |
178 | MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula"); | |
179 | MODULE_LICENSE("GPL v2"); | |
180 | MODULE_ALIAS("platform:byt-max98090"); |