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_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_CBM_CFM;
 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_CBM_CFM;
 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        .non_legacy_dai_naming  = 1,
 479};
 480
 481static int wl1273_platform_probe(struct platform_device *pdev)
 482{
 483        return devm_snd_soc_register_component(&pdev->dev,
 484                                      &soc_component_dev_wl1273,
 485                                      &wl1273_dai, 1);
 486}
 487
 488static int wl1273_platform_remove(struct platform_device *pdev)
 489{
 490        return 0;
 491}
 492
 493MODULE_ALIAS("platform:wl1273-codec");
 494
 495static struct platform_driver wl1273_platform_driver = {
 496        .driver         = {
 497                .name   = "wl1273-codec",
 498        },
 499        .probe          = wl1273_platform_probe,
 500        .remove         = wl1273_platform_remove,
 501};
 502
 503module_platform_driver(wl1273_platform_driver);
 504
 505MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
 506MODULE_DESCRIPTION("ASoC WL1273 codec driver");
 507MODULE_LICENSE("GPL");
 508