1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ALSA SoC WL1273 codec driver 4 * 5 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com> 6 * 7 * Copyright: (C) 2010, 2011 Nokia Corporation 8 */ 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 20 enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX }; 21 22 /* codec private data */ 23 struct wl1273_priv { 24 enum wl1273_mode mode; 25 struct wl1273_core *core; 26 unsigned int channels; 27 }; 28 29 static 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 } 123 out: 124 mutex_unlock(&core->lock); 125 126 return r; 127 } 128 129 static 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 else 151 r = -EINVAL; 152 out: 153 mutex_unlock(&core->lock); 154 155 return r; 156 } 157 158 static 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 control 171 * only indicates the setting that has been done elsewhere (in the user 172 * space). 173 */ 174 static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; 175 176 static 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 197 static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); 198 199 static 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 212 static 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 232 static const char * const wl1273_audio_strings[] = { "Digital", "Analog" }; 233 234 static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); 235 236 static 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 249 static 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 266 static 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 275 static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = { 276 SND_SOC_DAPM_INPUT("RX"), 277 278 SND_SOC_DAPM_OUTPUT("TX"), 279 }; 280 281 static const struct snd_soc_dapm_route wl1273_dapm_routes[] = { 282 { "Capture", NULL, "RX" }, 283 284 { "TX", NULL, "Playback" }, 285 }; 286 287 static 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 319 static 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 380 static const struct snd_soc_dai_ops wl1273_dai_ops = { 381 .startup = wl1273_startup, 382 .hw_params = wl1273_hw_params, 383 }; 384 385 static 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 */ 403 int 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 } 432 EXPORT_SYMBOL_GPL(wl1273_get_format); 433 434 static 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 458 static 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 466 static 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 480 static 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 487 MODULE_ALIAS("platform:wl1273-codec"); 488 489 static struct platform_driver wl1273_platform_driver = { 490 .driver = { 491 .name = "wl1273-codec", 492 }, 493 .probe = wl1273_platform_probe, 494 }; 495 496 module_platform_driver(wl1273_platform_driver); 497 498 MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); 499 MODULE_DESCRIPTION("ASoC WL1273 codec driver"); 500 MODULE_LICENSE("GPL"); 501
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.