501 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * ALSA SoC WL1273 codec driver4 *5 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>6 *7 * Copyright: (C) 2010, 2011 Nokia Corporation8 */9 10#include <linux/mfd/wl1273-core.h>11#include <linux/slab.h>12#include <linux/module.h>13#include <sound/pcm.h>14#include <sound/pcm_params.h>15#include <sound/soc.h>16#include <sound/initval.h>17 18#include "wl1273.h"19 20enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };21 22/* codec private data */23struct wl1273_priv {24 enum wl1273_mode mode;25 struct wl1273_core *core;26 unsigned int channels;27};28 29static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,30 int rate, int width)31{32 struct device *dev = &core->client->dev;33 int r = 0;34 u16 mode;35 36 dev_dbg(dev, "rate: %d\n", rate);37 dev_dbg(dev, "width: %d\n", width);38 39 mutex_lock(&core->lock);40 41 mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;42 43 switch (rate) {44 case 48000:45 mode |= WL1273_IS2_RATE_48K;46 break;47 case 44100:48 mode |= WL1273_IS2_RATE_44_1K;49 break;50 case 32000:51 mode |= WL1273_IS2_RATE_32K;52 break;53 case 22050:54 mode |= WL1273_IS2_RATE_22_05K;55 break;56 case 16000:57 mode |= WL1273_IS2_RATE_16K;58 break;59 case 12000:60 mode |= WL1273_IS2_RATE_12K;61 break;62 case 11025:63 mode |= WL1273_IS2_RATE_11_025;64 break;65 case 8000:66 mode |= WL1273_IS2_RATE_8K;67 break;68 default:69 dev_err(dev, "Sampling rate: %d not supported\n", rate);70 r = -EINVAL;71 goto out;72 }73 74 switch (width) {75 case 16:76 mode |= WL1273_IS2_WIDTH_32;77 break;78 case 20:79 mode |= WL1273_IS2_WIDTH_40;80 break;81 case 24:82 mode |= WL1273_IS2_WIDTH_48;83 break;84 case 25:85 mode |= WL1273_IS2_WIDTH_50;86 break;87 case 30:88 mode |= WL1273_IS2_WIDTH_60;89 break;90 case 32:91 mode |= WL1273_IS2_WIDTH_64;92 break;93 case 40:94 mode |= WL1273_IS2_WIDTH_80;95 break;96 case 48:97 mode |= WL1273_IS2_WIDTH_96;98 break;99 case 64:100 mode |= WL1273_IS2_WIDTH_128;101 break;102 default:103 dev_err(dev, "Data width: %d not supported\n", width);104 r = -EINVAL;105 goto out;106 }107 108 dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE);109 dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);110 dev_dbg(dev, "mode: 0x%04x\n", mode);111 112 if (core->i2s_mode != mode) {113 r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);114 if (r)115 goto out;116 117 core->i2s_mode = mode;118 r = core->write(core, WL1273_AUDIO_ENABLE,119 WL1273_AUDIO_ENABLE_I2S);120 if (r)121 goto out;122 }123out:124 mutex_unlock(&core->lock);125 126 return r;127}128 129static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,130 int channel_number)131{132 struct device *dev = &core->client->dev;133 int r = 0;134 135 dev_dbg(dev, "%s\n", __func__);136 137 mutex_lock(&core->lock);138 139 if (core->channel_number == channel_number)140 goto out;141 142 if (channel_number == 1 && core->mode == WL1273_MODE_RX)143 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);144 else if (channel_number == 1 && core->mode == WL1273_MODE_TX)145 r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);146 else if (channel_number == 2 && core->mode == WL1273_MODE_RX)147 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);148 else if (channel_number == 2 && core->mode == WL1273_MODE_TX)149 r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);150 else151 r = -EINVAL;152out:153 mutex_unlock(&core->lock);154 155 return r;156}157 158static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,159 struct snd_ctl_elem_value *ucontrol)160{161 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);162 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);163 164 ucontrol->value.enumerated.item[0] = wl1273->mode;165 166 return 0;167}168 169/*170 * TODO: Implement the audio routing in the driver. Now this control171 * only indicates the setting that has been done elsewhere (in the user172 * space).173 */174static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };175 176static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,177 struct snd_ctl_elem_value *ucontrol)178{179 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);180 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);181 182 if (wl1273->mode == ucontrol->value.enumerated.item[0])183 return 0;184 185 /* Do not allow changes while stream is running */186 if (snd_soc_component_active(component))187 return -EPERM;188 189 if (ucontrol->value.enumerated.item[0] >= ARRAY_SIZE(wl1273_audio_route))190 return -EINVAL;191 192 wl1273->mode = ucontrol->value.enumerated.item[0];193 194 return 1;195}196 197static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);198 199static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,200 struct snd_ctl_elem_value *ucontrol)201{202 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);203 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);204 205 dev_dbg(component->dev, "%s: enter.\n", __func__);206 207 ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;208 209 return 0;210}211 212static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,213 struct snd_ctl_elem_value *ucontrol)214{215 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);216 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);217 int val, r = 0;218 219 dev_dbg(component->dev, "%s: enter.\n", __func__);220 221 val = ucontrol->value.enumerated.item[0];222 if (wl1273->core->audio_mode == val)223 return 0;224 225 r = wl1273->core->set_audio(wl1273->core, val);226 if (r < 0)227 return r;228 229 return 1;230}231 232static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };233 234static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);235 236static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,237 struct snd_ctl_elem_value *ucontrol)238{239 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);240 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);241 242 dev_dbg(component->dev, "%s: enter.\n", __func__);243 244 ucontrol->value.integer.value[0] = wl1273->core->volume;245 246 return 0;247}248 249static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,250 struct snd_ctl_elem_value *ucontrol)251{252 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);253 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);254 int r;255 256 dev_dbg(component->dev, "%s: enter.\n", __func__);257 258 r = wl1273->core->set_volume(wl1273->core,259 ucontrol->value.integer.value[0]);260 if (r)261 return r;262 263 return 1;264}265 266static const struct snd_kcontrol_new wl1273_controls[] = {267 SOC_ENUM_EXT("Codec Mode", wl1273_enum,268 snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),269 SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,270 snd_wl1273_fm_audio_get, snd_wl1273_fm_audio_put),271 SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,272 snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),273};274 275static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {276 SND_SOC_DAPM_INPUT("RX"),277 278 SND_SOC_DAPM_OUTPUT("TX"),279};280 281static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {282 { "Capture", NULL, "RX" },283 284 { "TX", NULL, "Playback" },285};286 287static int wl1273_startup(struct snd_pcm_substream *substream,288 struct snd_soc_dai *dai)289{290 struct snd_soc_component *component = dai->component;291 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);292 293 switch (wl1273->mode) {294 case WL1273_MODE_BT:295 snd_pcm_hw_constraint_single(substream->runtime,296 SNDRV_PCM_HW_PARAM_RATE, 8000);297 snd_pcm_hw_constraint_single(substream->runtime,298 SNDRV_PCM_HW_PARAM_CHANNELS, 1);299 break;300 case WL1273_MODE_FM_RX:301 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {302 pr_err("Cannot play in RX mode.\n");303 return -EINVAL;304 }305 break;306 case WL1273_MODE_FM_TX:307 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {308 pr_err("Cannot capture in TX mode.\n");309 return -EINVAL;310 }311 break;312 default:313 return -EINVAL;314 }315 316 return 0;317}318 319static int wl1273_hw_params(struct snd_pcm_substream *substream,320 struct snd_pcm_hw_params *params,321 struct snd_soc_dai *dai)322{323 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);324 struct wl1273_core *core = wl1273->core;325 unsigned int rate, width, r;326 327 if (params_width(params) != 16) {328 dev_err(dai->dev, "%d bits/sample not supported\n",329 params_width(params));330 return -EINVAL;331 }332 333 rate = params_rate(params);334 width = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;335 336 if (wl1273->mode == WL1273_MODE_BT) {337 if (rate != 8000) {338 pr_err("Rate %d not supported.\n", params_rate(params));339 return -EINVAL;340 }341 342 if (params_channels(params) != 1) {343 pr_err("Only mono supported.\n");344 return -EINVAL;345 }346 347 return 0;348 }349 350 if (wl1273->mode == WL1273_MODE_FM_TX &&351 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {352 pr_err("Only playback supported with TX.\n");353 return -EINVAL;354 }355 356 if (wl1273->mode == WL1273_MODE_FM_RX &&357 substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {358 pr_err("Only capture supported with RX.\n");359 return -EINVAL;360 }361 362 if (wl1273->mode != WL1273_MODE_FM_RX &&363 wl1273->mode != WL1273_MODE_FM_TX) {364 pr_err("Unexpected mode: %d.\n", wl1273->mode);365 return -EINVAL;366 }367 368 r = snd_wl1273_fm_set_i2s_mode(core, rate, width);369 if (r)370 return r;371 372 wl1273->channels = params_channels(params);373 r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);374 if (r)375 return r;376 377 return 0;378}379 380static const struct snd_soc_dai_ops wl1273_dai_ops = {381 .startup = wl1273_startup,382 .hw_params = wl1273_hw_params,383};384 385static struct snd_soc_dai_driver wl1273_dai = {386 .name = "wl1273-fm",387 .playback = {388 .stream_name = "Playback",389 .channels_min = 1,390 .channels_max = 2,391 .rates = SNDRV_PCM_RATE_8000_48000,392 .formats = SNDRV_PCM_FMTBIT_S16_LE},393 .capture = {394 .stream_name = "Capture",395 .channels_min = 1,396 .channels_max = 2,397 .rates = SNDRV_PCM_RATE_8000_48000,398 .formats = SNDRV_PCM_FMTBIT_S16_LE},399 .ops = &wl1273_dai_ops,400};401 402/* Audio interface format for the soc_card driver */403int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)404{405 struct wl1273_priv *wl1273;406 407 if (component == NULL || fmt == NULL)408 return -EINVAL;409 410 wl1273 = snd_soc_component_get_drvdata(component);411 412 switch (wl1273->mode) {413 case WL1273_MODE_FM_RX:414 case WL1273_MODE_FM_TX:415 *fmt = SND_SOC_DAIFMT_I2S |416 SND_SOC_DAIFMT_NB_NF |417 SND_SOC_DAIFMT_CBP_CFP;418 419 break;420 case WL1273_MODE_BT:421 *fmt = SND_SOC_DAIFMT_DSP_A |422 SND_SOC_DAIFMT_IB_NF |423 SND_SOC_DAIFMT_CBP_CFP;424 425 break;426 default:427 return -EINVAL;428 }429 430 return 0;431}432EXPORT_SYMBOL_GPL(wl1273_get_format);433 434static int wl1273_probe(struct snd_soc_component *component)435{436 struct wl1273_core **core = component->dev->platform_data;437 struct wl1273_priv *wl1273;438 439 dev_dbg(component->dev, "%s.\n", __func__);440 441 if (!core) {442 dev_err(component->dev, "Platform data is missing.\n");443 return -EINVAL;444 }445 446 wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);447 if (!wl1273)448 return -ENOMEM;449 450 wl1273->mode = WL1273_MODE_BT;451 wl1273->core = *core;452 453 snd_soc_component_set_drvdata(component, wl1273);454 455 return 0;456}457 458static void wl1273_remove(struct snd_soc_component *component)459{460 struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);461 462 dev_dbg(component->dev, "%s\n", __func__);463 kfree(wl1273);464}465 466static const struct snd_soc_component_driver soc_component_dev_wl1273 = {467 .probe = wl1273_probe,468 .remove = wl1273_remove,469 .controls = wl1273_controls,470 .num_controls = ARRAY_SIZE(wl1273_controls),471 .dapm_widgets = wl1273_dapm_widgets,472 .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),473 .dapm_routes = wl1273_dapm_routes,474 .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),475 .idle_bias_on = 1,476 .use_pmdown_time = 1,477 .endianness = 1,478};479 480static int wl1273_platform_probe(struct platform_device *pdev)481{482 return devm_snd_soc_register_component(&pdev->dev,483 &soc_component_dev_wl1273,484 &wl1273_dai, 1);485}486 487MODULE_ALIAS("platform:wl1273-codec");488 489static struct platform_driver wl1273_platform_driver = {490 .driver = {491 .name = "wl1273-codec",492 },493 .probe = wl1273_platform_probe,494};495 496module_platform_driver(wl1273_platform_driver);497 498MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");499MODULE_DESCRIPTION("ASoC WL1273 codec driver");500MODULE_LICENSE("GPL");501