1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Driver for generic Bluetooth SCO link |
4 | * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> |
5 | */ |
6 | |
7 | #include <linux/init.h> |
8 | #include <linux/module.h> |
9 | #include <linux/platform_device.h> |
10 | |
11 | #include <sound/soc.h> |
12 | |
13 | static const struct snd_soc_dapm_widget bt_sco_widgets[] = { |
14 | SND_SOC_DAPM_INPUT("RX" ), |
15 | SND_SOC_DAPM_OUTPUT("TX" ), |
16 | SND_SOC_DAPM_AIF_IN("BT_SCO_RX" , "Playback" , 0, |
17 | SND_SOC_NOPM, 0, 0), |
18 | SND_SOC_DAPM_AIF_OUT("BT_SCO_TX" , "Capture" , 0, |
19 | SND_SOC_NOPM, 0, 0), |
20 | }; |
21 | |
22 | static const struct snd_soc_dapm_route bt_sco_routes[] = { |
23 | { "BT_SCO_TX" , NULL, "RX" }, |
24 | { "TX" , NULL, "BT_SCO_RX" }, |
25 | }; |
26 | |
27 | static struct snd_soc_dai_driver bt_sco_dai[] = { |
28 | { |
29 | .name = "bt-sco-pcm" , |
30 | .playback = { |
31 | .stream_name = "Playback" , |
32 | .channels_min = 1, |
33 | .channels_max = 1, |
34 | .rates = SNDRV_PCM_RATE_8000, |
35 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
36 | }, |
37 | .capture = { |
38 | .stream_name = "Capture" , |
39 | .channels_min = 1, |
40 | .channels_max = 1, |
41 | .rates = SNDRV_PCM_RATE_8000, |
42 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
43 | }, |
44 | }, |
45 | { |
46 | .name = "bt-sco-pcm-wb" , |
47 | .playback = { |
48 | .stream_name = "Playback" , |
49 | .channels_min = 1, |
50 | .channels_max = 1, |
51 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, |
52 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
53 | }, |
54 | .capture = { |
55 | .stream_name = "Capture" , |
56 | .channels_min = 1, |
57 | .channels_max = 1, |
58 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, |
59 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
60 | }, |
61 | } |
62 | }; |
63 | |
64 | static const struct snd_soc_component_driver soc_component_dev_bt_sco = { |
65 | .dapm_widgets = bt_sco_widgets, |
66 | .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), |
67 | .dapm_routes = bt_sco_routes, |
68 | .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), |
69 | .idle_bias_on = 1, |
70 | .use_pmdown_time = 1, |
71 | .endianness = 1, |
72 | }; |
73 | |
74 | static int bt_sco_probe(struct platform_device *pdev) |
75 | { |
76 | return devm_snd_soc_register_component(dev: &pdev->dev, |
77 | component_driver: &soc_component_dev_bt_sco, |
78 | dai_drv: bt_sco_dai, ARRAY_SIZE(bt_sco_dai)); |
79 | } |
80 | |
81 | static const struct platform_device_id bt_sco_driver_ids[] = { |
82 | { |
83 | .name = "dfbmcs320" , |
84 | }, |
85 | { |
86 | .name = "bt-sco" , |
87 | }, |
88 | {}, |
89 | }; |
90 | MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids); |
91 | |
92 | #if defined(CONFIG_OF) |
93 | static const struct of_device_id bt_sco_codec_of_match[] = { |
94 | { .compatible = "delta,dfbmcs320" , }, |
95 | { .compatible = "linux,bt-sco" , }, |
96 | {}, |
97 | }; |
98 | MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match); |
99 | #endif |
100 | |
101 | static struct platform_driver bt_sco_driver = { |
102 | .driver = { |
103 | .name = "bt-sco" , |
104 | .of_match_table = of_match_ptr(bt_sco_codec_of_match), |
105 | }, |
106 | .probe = bt_sco_probe, |
107 | .id_table = bt_sco_driver_ids, |
108 | }; |
109 | |
110 | module_platform_driver(bt_sco_driver); |
111 | |
112 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>" ); |
113 | MODULE_DESCRIPTION("ASoC generic bluetooth sco link driver" ); |
114 | MODULE_LICENSE("GPL" ); |
115 | |