linux/sound/soc/codecs/tlv320aic26.c
<<
>>
Prefs
   1/*
   2 * Texas Instruments TLV320AIC26 low power audio CODEC
   3 * ALSA SoC CODEC driver
   4 *
   5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/moduleparam.h>
  10#include <linux/init.h>
  11#include <linux/delay.h>
  12#include <linux/pm.h>
  13#include <linux/device.h>
  14#include <linux/sysfs.h>
  15#include <linux/spi/spi.h>
  16#include <linux/slab.h>
  17#include <sound/core.h>
  18#include <sound/pcm.h>
  19#include <sound/pcm_params.h>
  20#include <sound/soc.h>
  21#include <sound/initval.h>
  22
  23#include "tlv320aic26.h"
  24
  25MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
  26MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
  27MODULE_LICENSE("GPL");
  28
  29/* AIC26 driver private data */
  30struct aic26 {
  31        struct spi_device *spi;
  32        struct regmap *regmap;
  33        struct snd_soc_codec *codec;
  34        int master;
  35        int datfm;
  36        int mclk;
  37
  38        /* Keyclick parameters */
  39        int keyclick_amplitude;
  40        int keyclick_freq;
  41        int keyclick_len;
  42};
  43
  44static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = {
  45SND_SOC_DAPM_INPUT("MICIN"),
  46SND_SOC_DAPM_INPUT("AUX"),
  47
  48SND_SOC_DAPM_OUTPUT("HPL"),
  49SND_SOC_DAPM_OUTPUT("HPR"),
  50};
  51
  52static const struct snd_soc_dapm_route tlv320aic26_dapm_routes[] = {
  53        { "Capture", NULL, "MICIN" },
  54        { "Capture", NULL, "AUX" },
  55
  56        { "HPL", NULL, "Playback" },
  57        { "HPR", NULL, "Playback" },
  58};
  59
  60/* ---------------------------------------------------------------------
  61 * Digital Audio Interface Operations
  62 */
  63static int aic26_hw_params(struct snd_pcm_substream *substream,
  64                           struct snd_pcm_hw_params *params,
  65                           struct snd_soc_dai *dai)
  66{
  67        struct snd_soc_codec *codec = dai->codec;
  68        struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
  69        int fsref, divisor, wlen, pval, jval, dval, qval;
  70        u16 reg;
  71
  72        dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
  73                substream, params);
  74        dev_dbg(&aic26->spi->dev, "rate=%i width=%d\n", params_rate(params),
  75                params_width(params));
  76
  77        switch (params_rate(params)) {
  78        case 8000:  fsref = 48000; divisor = AIC26_DIV_6; break;
  79        case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
  80        case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
  81        case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
  82        case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
  83        case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
  84        case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
  85        case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
  86        case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
  87        default:
  88                dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
  89        }
  90
  91        /* select data word length */
  92        switch (params_width(params)) {
  93        case 8:  wlen = AIC26_WLEN_16; break;
  94        case 16: wlen = AIC26_WLEN_16; break;
  95        case 24: wlen = AIC26_WLEN_24; break;
  96        case 32: wlen = AIC26_WLEN_32; break;
  97        default:
  98                dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
  99        }
 100
 101        /**
 102         * Configure PLL
 103         * fsref = (mclk * PLLM) / 2048
 104         * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal)
 105         */
 106        pval = 1;
 107        /* compute J portion of multiplier */
 108        jval = fsref / (aic26->mclk / 2048);
 109        /* compute fractional DDDD component of multiplier */
 110        dval = fsref - (jval * (aic26->mclk / 2048));
 111        dval = (10000 * dval) / (aic26->mclk / 2048);
 112        dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
 113        qval = 0;
 114        reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
 115        snd_soc_write(codec, AIC26_REG_PLL_PROG1, reg);
 116        reg = dval << 2;
 117        snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
 118
 119        /* Audio Control 3 (master mode, fsref rate) */
 120        if (aic26->master)
 121                reg = 0x0800;
 122        if (fsref == 48000)
 123                reg = 0x2000;
 124        snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0xf800, reg);
 125
 126        /* Audio Control 1 (FSref divisor) */
 127        reg = wlen | aic26->datfm | (divisor << 3) | divisor;
 128        snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL1, 0xfff, reg);
 129
 130        return 0;
 131}
 132
 133/**
 134 * aic26_mute - Mute control to reduce noise when changing audio format
 135 */
 136static int aic26_mute(struct snd_soc_dai *dai, int mute)
 137{
 138        struct snd_soc_codec *codec = dai->codec;
 139        struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
 140        u16 reg;
 141
 142        dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
 143                dai, mute);
 144
 145        if (mute)
 146                reg = 0x8080;
 147        else
 148                reg = 0;
 149        snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8000, reg);
 150
 151        return 0;
 152}
 153
 154static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
 155                            int clk_id, unsigned int freq, int dir)
 156{
 157        struct snd_soc_codec *codec = codec_dai->codec;
 158        struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
 159
 160        dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
 161                " freq=%i, dir=%i)\n",
 162                codec_dai, clk_id, freq, dir);
 163
 164        /* MCLK needs to fall between 2MHz and 50 MHz */
 165        if ((freq < 2000000) || (freq > 50000000))
 166                return -EINVAL;
 167
 168        aic26->mclk = freq;
 169        return 0;
 170}
 171
 172static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 173{
 174        struct snd_soc_codec *codec = codec_dai->codec;
 175        struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
 176
 177        dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
 178                codec_dai, fmt);
 179
 180        /* set master/slave audio interface */
 181        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 182        case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
 183        case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
 184        default:
 185                dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
 186        }
 187
 188        /* interface format */
 189        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 190        case SND_SOC_DAIFMT_I2S:     aic26->datfm = AIC26_DATFM_I2S; break;
 191        case SND_SOC_DAIFMT_DSP_A:   aic26->datfm = AIC26_DATFM_DSP; break;
 192        case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
 193        case SND_SOC_DAIFMT_LEFT_J:  aic26->datfm = AIC26_DATFM_LEFTJ; break;
 194        default:
 195                dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
 196        }
 197
 198        return 0;
 199}
 200
 201/* ---------------------------------------------------------------------
 202 * Digital Audio Interface Definition
 203 */
 204#define AIC26_RATES     (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
 205                         SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
 206                         SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
 207                         SNDRV_PCM_RATE_48000)
 208#define AIC26_FORMATS   (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_BE |\
 209                         SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
 210
 211static const struct snd_soc_dai_ops aic26_dai_ops = {
 212        .hw_params      = aic26_hw_params,
 213        .digital_mute   = aic26_mute,
 214        .set_sysclk     = aic26_set_sysclk,
 215        .set_fmt        = aic26_set_fmt,
 216};
 217
 218static struct snd_soc_dai_driver aic26_dai = {
 219        .name = "tlv320aic26-hifi",
 220        .playback = {
 221                .stream_name = "Playback",
 222                .channels_min = 2,
 223                .channels_max = 2,
 224                .rates = AIC26_RATES,
 225                .formats = AIC26_FORMATS,
 226        },
 227        .capture = {
 228                .stream_name = "Capture",
 229                .channels_min = 2,
 230                .channels_max = 2,
 231                .rates = AIC26_RATES,
 232                .formats = AIC26_FORMATS,
 233        },
 234        .ops = &aic26_dai_ops,
 235};
 236
 237/* ---------------------------------------------------------------------
 238 * ALSA controls
 239 */
 240static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
 241static SOC_ENUM_SINGLE_DECL(aic26_capture_src_enum,
 242                            AIC26_REG_AUDIO_CTRL1, 12,
 243                            aic26_capture_src_text);
 244
 245static const struct snd_kcontrol_new aic26_snd_controls[] = {
 246        /* Output */
 247        SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
 248        SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
 249        SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
 250        SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
 251        SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
 252        SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
 253        SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
 254        SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
 255        SOC_ENUM("Capture Source", aic26_capture_src_enum),
 256};
 257
 258/* ---------------------------------------------------------------------
 259 * SPI device portion of driver: sysfs files for debugging
 260 */
 261
 262static ssize_t aic26_keyclick_show(struct device *dev,
 263                                   struct device_attribute *attr, char *buf)
 264{
 265        struct aic26 *aic26 = dev_get_drvdata(dev);
 266        int val, amp, freq, len;
 267
 268        val = snd_soc_read(aic26->codec, AIC26_REG_AUDIO_CTRL2);
 269        amp = (val >> 12) & 0x7;
 270        freq = (125 << ((val >> 8) & 0x7)) >> 1;
 271        len = 2 * (1 + ((val >> 4) & 0xf));
 272
 273        return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
 274}
 275
 276/* Any write to the keyclick attribute will trigger the keyclick event */
 277static ssize_t aic26_keyclick_set(struct device *dev,
 278                                  struct device_attribute *attr,
 279                                  const char *buf, size_t count)
 280{
 281        struct aic26 *aic26 = dev_get_drvdata(dev);
 282
 283        snd_soc_update_bits(aic26->codec, AIC26_REG_AUDIO_CTRL2,
 284                            0x8000, 0x800);
 285
 286        return count;
 287}
 288
 289static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
 290
 291/* ---------------------------------------------------------------------
 292 * SoC CODEC portion of driver: probe and release routines
 293 */
 294static int aic26_probe(struct snd_soc_codec *codec)
 295{
 296        struct aic26 *aic26 = dev_get_drvdata(codec->dev);
 297        int ret, reg;
 298
 299        aic26->codec = codec;
 300
 301        /* Reset the codec to power on defaults */
 302        snd_soc_write(codec, AIC26_REG_RESET, 0xBB00);
 303
 304        /* Power up CODEC */
 305        snd_soc_write(codec, AIC26_REG_POWER_CTRL, 0);
 306
 307        /* Audio Control 3 (master mode, fsref rate) */
 308        reg = snd_soc_read(codec, AIC26_REG_AUDIO_CTRL3);
 309        reg &= ~0xf800;
 310        reg |= 0x0800; /* set master mode */
 311        snd_soc_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
 312
 313        /* Register the sysfs files for debugging */
 314        /* Create SysFS files */
 315        ret = device_create_file(codec->dev, &dev_attr_keyclick);
 316        if (ret)
 317                dev_info(codec->dev, "error creating sysfs files\n");
 318
 319        return 0;
 320}
 321
 322static struct snd_soc_codec_driver aic26_soc_codec_dev = {
 323        .probe = aic26_probe,
 324        .controls = aic26_snd_controls,
 325        .num_controls = ARRAY_SIZE(aic26_snd_controls),
 326        .dapm_widgets = tlv320aic26_dapm_widgets,
 327        .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets),
 328        .dapm_routes = tlv320aic26_dapm_routes,
 329        .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
 330};
 331
 332static const struct regmap_config aic26_regmap = {
 333        .reg_bits = 16,
 334        .val_bits = 16,
 335};
 336
 337/* ---------------------------------------------------------------------
 338 * SPI device portion of driver: probe and release routines and SPI
 339 *                               driver registration.
 340 */
 341static int aic26_spi_probe(struct spi_device *spi)
 342{
 343        struct aic26 *aic26;
 344        int ret;
 345
 346        dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
 347
 348        /* Allocate driver data */
 349        aic26 = devm_kzalloc(&spi->dev, sizeof *aic26, GFP_KERNEL);
 350        if (!aic26)
 351                return -ENOMEM;
 352
 353        aic26->regmap = devm_regmap_init_spi(spi, &aic26_regmap);
 354        if (IS_ERR(aic26->regmap))
 355                return PTR_ERR(aic26->regmap);
 356
 357        /* Initialize the driver data */
 358        aic26->spi = spi;
 359        dev_set_drvdata(&spi->dev, aic26);
 360        aic26->master = 1;
 361
 362        ret = snd_soc_register_codec(&spi->dev,
 363                        &aic26_soc_codec_dev, &aic26_dai, 1);
 364        return ret;
 365}
 366
 367static int aic26_spi_remove(struct spi_device *spi)
 368{
 369        snd_soc_unregister_codec(&spi->dev);
 370        return 0;
 371}
 372
 373static struct spi_driver aic26_spi = {
 374        .driver = {
 375                .name = "tlv320aic26-codec",
 376                .owner = THIS_MODULE,
 377        },
 378        .probe = aic26_spi_probe,
 379        .remove = aic26_spi_remove,
 380};
 381
 382module_spi_driver(aic26_spi);
 383