linux/sound/soc/codecs/wl1273.c
<<
>>
Prefs
   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
  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        else
 151                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 control
 171 * only indicates the setting that has been done elsewhere (in the user
 172 * 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_is_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                break;
 315        }
 316
 317        return 0;
 318}
 319
 320static int wl1273_hw_params(struct snd_pcm_substream *substream,
 321                            struct snd_pcm_hw_params *params,
 322                            struct snd_soc_dai *dai)
 323{
 324        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);
 325        struct wl1273_core *core = wl1273->core;
 326        unsigned int rate, width, r;
 327
 328        if (params_width(params) != 16) {
 329                dev_err(dai->dev, "%d bits/sample not supported\n",
 330                        params_width(params));
 331                return -EINVAL;
 332        }
 333
 334        rate = params_rate(params);
 335        width =  hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
 336
 337        if (wl1273->mode == WL1273_MODE_BT) {
 338                if (rate != 8000) {
 339                        pr_err("Rate %d not supported.\n", params_rate(params));
 340                        return -EINVAL;
 341                }
 342
 343                if (params_channels(params) != 1) {
 344                        pr_err("Only mono supported.\n");
 345                        return -EINVAL;
 346                }
 347
 348                return 0;
 349        }
 350
 351        if (wl1273->mode == WL1273_MODE_FM_TX &&
 352            substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 353                pr_err("Only playback supported with TX.\n");
 354                return -EINVAL;
 355        }
 356
 357        if (wl1273->mode == WL1273_MODE_FM_RX  &&
 358            substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 359                pr_err("Only capture supported with RX.\n");
 360                return -EINVAL;
 361        }
 362
 363        if (wl1273->mode != WL1273_MODE_FM_RX  &&
 364            wl1273->mode != WL1273_MODE_FM_TX) {
 365                pr_err("Unexpected mode: %d.\n", wl1273->mode);
 366                return -EINVAL;
 367        }
 368
 369        r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
 370        if (r)
 371                return r;
 372
 373        wl1273->channels = params_channels(params);
 374        r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
 375        if (r)
 376                return r;
 377
 378        return 0;
 379}
 380
 381static const struct snd_soc_dai_ops wl1273_dai_ops = {
 382        .startup        = wl1273_startup,
 383        .hw_params      = wl1273_hw_params,
 384};
 385
 386static struct snd_soc_dai_driver wl1273_dai = {
 387        .name = "wl1273-fm",
 388        .playback = {
 389                .stream_name = "Playback",
 390                .channels_min = 1,
 391                .channels_max = 2,
 392                .rates = SNDRV_PCM_RATE_8000_48000,
 393                .formats = SNDRV_PCM_FMTBIT_S16_LE},
 394        .capture = {
 395                .stream_name = "Capture",
 396                .channels_min = 1,
 397                .channels_max = 2,
 398                .rates = SNDRV_PCM_RATE_8000_48000,
 399                .formats = SNDRV_PCM_FMTBIT_S16_LE},
 400        .ops = &wl1273_dai_ops,
 401};
 402
 403/* Audio interface format for the soc_card driver */
 404int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)
 405{
 406        struct wl1273_priv *wl1273;
 407
 408        if (component == NULL || fmt == NULL)
 409                return -EINVAL;
 410
 411        wl1273 = snd_soc_component_get_drvdata(component);
 412
 413        switch (wl1273->mode) {
 414        case WL1273_MODE_FM_RX:
 415        case WL1273_MODE_FM_TX:
 416                *fmt =  SND_SOC_DAIFMT_I2S |
 417                        SND_SOC_DAIFMT_NB_NF |
 418                        SND_SOC_DAIFMT_CBM_CFM;
 419
 420                break;
 421        case WL1273_MODE_BT:
 422                *fmt =  SND_SOC_DAIFMT_DSP_A |
 423                        SND_SOC_DAIFMT_IB_NF |
 424                        SND_SOC_DAIFMT_CBM_CFM;
 425
 426                break;
 427        default:
 428                return -EINVAL;
 429        }
 430
 431        return 0;
 432}
 433EXPORT_SYMBOL_GPL(wl1273_get_format);
 434
 435static int wl1273_probe(struct snd_soc_component *component)
 436{
 437        struct wl1273_core **core = component->dev->platform_data;
 438        struct wl1273_priv *wl1273;
 439
 440        dev_dbg(component->dev, "%s.\n", __func__);
 441
 442        if (!core) {
 443                dev_err(component->dev, "Platform data is missing.\n");
 444                return -EINVAL;
 445        }
 446
 447        wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
 448        if (!wl1273)
 449                return -ENOMEM;
 450
 451        wl1273->mode = WL1273_MODE_BT;
 452        wl1273->core = *core;
 453
 454        snd_soc_component_set_drvdata(component, wl1273);
 455
 456        return 0;
 457}
 458
 459static void wl1273_remove(struct snd_soc_component *component)
 460{
 461        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 462
 463        dev_dbg(component->dev, "%s\n", __func__);
 464        kfree(wl1273);
 465}
 466
 467static const struct snd_soc_component_driver soc_component_dev_wl1273 = {
 468        .probe                  = wl1273_probe,
 469        .remove                 = wl1273_remove,
 470        .controls               = wl1273_controls,
 471        .num_controls           = ARRAY_SIZE(wl1273_controls),
 472        .dapm_widgets           = wl1273_dapm_widgets,
 473        .num_dapm_widgets       = ARRAY_SIZE(wl1273_dapm_widgets),
 474        .dapm_routes            = wl1273_dapm_routes,
 475        .num_dapm_routes        = ARRAY_SIZE(wl1273_dapm_routes),
 476        .idle_bias_on           = 1,
 477        .use_pmdown_time        = 1,
 478        .endianness             = 1,
 479        .non_legacy_dai_naming  = 1,
 480};
 481
 482static int wl1273_platform_probe(struct platform_device *pdev)
 483{
 484        return devm_snd_soc_register_component(&pdev->dev,
 485                                      &soc_component_dev_wl1273,
 486                                      &wl1273_dai, 1);
 487}
 488
 489static int wl1273_platform_remove(struct platform_device *pdev)
 490{
 491        return 0;
 492}
 493
 494MODULE_ALIAS("platform:wl1273-codec");
 495
 496static struct platform_driver wl1273_platform_driver = {
 497        .driver         = {
 498                .name   = "wl1273-codec",
 499        },
 500        .probe          = wl1273_platform_probe,
 501        .remove         = wl1273_platform_remove,
 502};
 503
 504module_platform_driver(wl1273_platform_driver);
 505
 506MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
 507MODULE_DESCRIPTION("ASoC WL1273 codec driver");
 508MODULE_LICENSE("GPL");
 509