linux/sound/soc/codecs/adau7118.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver
   4//
   5// Copyright 2019 Analog Devices Inc.
   6
   7#include <linux/bitfield.h>
   8#include <linux/module.h>
   9#include <linux/regmap.h>
  10#include <linux/regulator/consumer.h>
  11#include <sound/pcm_params.h>
  12#include <sound/soc.h>
  13
  14#include "adau7118.h"
  15
  16#define ADAU7118_DEC_RATIO_MASK         GENMASK(1, 0)
  17#define ADAU7118_DEC_RATIO(x)           FIELD_PREP(ADAU7118_DEC_RATIO_MASK, x)
  18#define ADAU7118_CLK_MAP_MASK           GENMASK(7, 4)
  19#define ADAU7118_SLOT_WIDTH_MASK        GENMASK(5, 4)
  20#define ADAU7118_SLOT_WIDTH(x)          FIELD_PREP(ADAU7118_SLOT_WIDTH_MASK, x)
  21#define ADAU7118_TRISTATE_MASK          BIT(6)
  22#define ADAU7118_TRISTATE(x)            FIELD_PREP(ADAU7118_TRISTATE_MASK, x)
  23#define ADAU7118_DATA_FMT_MASK          GENMASK(3, 1)
  24#define ADAU7118_DATA_FMT(x)            FIELD_PREP(ADAU7118_DATA_FMT_MASK, x)
  25#define ADAU7118_SAI_MODE_MASK          BIT(0)
  26#define ADAU7118_SAI_MODE(x)            FIELD_PREP(ADAU7118_SAI_MODE_MASK, x)
  27#define ADAU7118_LRCLK_BCLK_POL_MASK    GENMASK(1, 0)
  28#define ADAU7118_LRCLK_BCLK_POL(x) \
  29                                FIELD_PREP(ADAU7118_LRCLK_BCLK_POL_MASK, x)
  30#define ADAU7118_SPT_SLOT_MASK          GENMASK(7, 4)
  31#define ADAU7118_SPT_SLOT(x)            FIELD_PREP(ADAU7118_SPT_SLOT_MASK, x)
  32#define ADAU7118_FULL_SOFT_R_MASK       BIT(1)
  33#define ADAU7118_FULL_SOFT_R(x)         FIELD_PREP(ADAU7118_FULL_SOFT_R_MASK, x)
  34
  35struct adau7118_data {
  36        struct regmap *map;
  37        struct device *dev;
  38        struct regulator *iovdd;
  39        struct regulator *dvdd;
  40        u32 slot_width;
  41        u32 slots;
  42        bool hw_mode;
  43        bool right_j;
  44};
  45
  46/* Input Enable */
  47static const struct snd_kcontrol_new adau7118_dapm_pdm_control[4] = {
  48        SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 0, 1, 0),
  49        SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 1, 1, 0),
  50        SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 2, 1, 0),
  51        SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 3, 1, 0),
  52};
  53
  54static const struct snd_soc_dapm_widget adau7118_widgets_sw[] = {
  55        /* Input Enable Switches */
  56        SND_SOC_DAPM_SWITCH("PDM0", SND_SOC_NOPM, 0, 0,
  57                            &adau7118_dapm_pdm_control[0]),
  58        SND_SOC_DAPM_SWITCH("PDM1", SND_SOC_NOPM, 0, 0,
  59                            &adau7118_dapm_pdm_control[1]),
  60        SND_SOC_DAPM_SWITCH("PDM2", SND_SOC_NOPM, 0, 0,
  61                            &adau7118_dapm_pdm_control[2]),
  62        SND_SOC_DAPM_SWITCH("PDM3", SND_SOC_NOPM, 0, 0,
  63                            &adau7118_dapm_pdm_control[3]),
  64
  65        /* PDM Clocks */
  66        SND_SOC_DAPM_SUPPLY("PDM_CLK0", ADAU7118_REG_ENABLES, 4, 0, NULL, 0),
  67        SND_SOC_DAPM_SUPPLY("PDM_CLK1", ADAU7118_REG_ENABLES, 5, 0, NULL, 0),
  68
  69        /* Output channels */
  70        SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, ADAU7118_REG_SPT_CX(0),
  71                             0, 0),
  72        SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 0, ADAU7118_REG_SPT_CX(1),
  73                             0, 0),
  74        SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 0, ADAU7118_REG_SPT_CX(2),
  75                             0, 0),
  76        SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 0, ADAU7118_REG_SPT_CX(3),
  77                             0, 0),
  78        SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 0, ADAU7118_REG_SPT_CX(4),
  79                             0, 0),
  80        SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 0, ADAU7118_REG_SPT_CX(5),
  81                             0, 0),
  82        SND_SOC_DAPM_AIF_OUT("AIF1TX7", "Capture", 0, ADAU7118_REG_SPT_CX(6),
  83                             0, 0),
  84        SND_SOC_DAPM_AIF_OUT("AIF1TX8", "Capture", 0, ADAU7118_REG_SPT_CX(7),
  85                             0, 0),
  86};
  87
  88static const struct snd_soc_dapm_route adau7118_routes_sw[] = {
  89        { "PDM0", "Capture Switch", "PDM_DAT0" },
  90        { "PDM1", "Capture Switch", "PDM_DAT1" },
  91        { "PDM2", "Capture Switch", "PDM_DAT2" },
  92        { "PDM3", "Capture Switch", "PDM_DAT3" },
  93        { "AIF1TX1", NULL, "PDM0" },
  94        { "AIF1TX2", NULL, "PDM0" },
  95        { "AIF1TX3", NULL, "PDM1" },
  96        { "AIF1TX4", NULL, "PDM1" },
  97        { "AIF1TX5", NULL, "PDM2" },
  98        { "AIF1TX6", NULL, "PDM2" },
  99        { "AIF1TX7", NULL, "PDM3" },
 100        { "AIF1TX8", NULL, "PDM3" },
 101        { "Capture", NULL, "PDM_CLK0" },
 102        { "Capture", NULL, "PDM_CLK1" },
 103};
 104
 105static const struct snd_soc_dapm_widget adau7118_widgets_hw[] = {
 106        SND_SOC_DAPM_AIF_OUT("AIF1TX", "Capture", 0, SND_SOC_NOPM, 0, 0),
 107};
 108
 109static const struct snd_soc_dapm_route adau7118_routes_hw[] = {
 110        { "AIF1TX", NULL, "PDM_DAT0" },
 111        { "AIF1TX", NULL, "PDM_DAT1" },
 112        { "AIF1TX", NULL, "PDM_DAT2" },
 113        { "AIF1TX", NULL, "PDM_DAT3" },
 114};
 115
 116static const struct snd_soc_dapm_widget adau7118_widgets[] = {
 117        SND_SOC_DAPM_INPUT("PDM_DAT0"),
 118        SND_SOC_DAPM_INPUT("PDM_DAT1"),
 119        SND_SOC_DAPM_INPUT("PDM_DAT2"),
 120        SND_SOC_DAPM_INPUT("PDM_DAT3"),
 121};
 122
 123static int adau7118_set_channel_map(struct snd_soc_dai *dai,
 124                                    unsigned int tx_num, unsigned int *tx_slot,
 125                                    unsigned int rx_num, unsigned int *rx_slot)
 126{
 127        struct adau7118_data *st =
 128                snd_soc_component_get_drvdata(dai->component);
 129        int chan, ret;
 130
 131        dev_dbg(st->dev, "Set channel map, %d", tx_num);
 132
 133        for (chan = 0; chan < tx_num; chan++) {
 134                ret = snd_soc_component_update_bits(dai->component,
 135                                        ADAU7118_REG_SPT_CX(chan),
 136                                        ADAU7118_SPT_SLOT_MASK,
 137                                        ADAU7118_SPT_SLOT(tx_slot[chan]));
 138                if (ret < 0)
 139                        return ret;
 140        }
 141
 142        return 0;
 143}
 144
 145static int adau7118_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 146{
 147        struct adau7118_data *st =
 148                snd_soc_component_get_drvdata(dai->component);
 149        int ret = 0;
 150        u32 regval;
 151
 152        dev_dbg(st->dev, "Set format, fmt:%d\n", fmt);
 153
 154        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 155        case SND_SOC_DAIFMT_I2S:
 156                ret = snd_soc_component_update_bits(dai->component,
 157                                                    ADAU7118_REG_SPT_CTRL1,
 158                                                    ADAU7118_DATA_FMT_MASK,
 159                                                    ADAU7118_DATA_FMT(0));
 160                break;
 161        case SND_SOC_DAIFMT_LEFT_J:
 162                ret = snd_soc_component_update_bits(dai->component,
 163                                                    ADAU7118_REG_SPT_CTRL1,
 164                                                    ADAU7118_DATA_FMT_MASK,
 165                                                    ADAU7118_DATA_FMT(1));
 166                break;
 167        case SND_SOC_DAIFMT_RIGHT_J:
 168                st->right_j = true;
 169                break;
 170        default:
 171                dev_err(st->dev, "Invalid format %d",
 172                        fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 173                return -EINVAL;
 174        }
 175
 176        if (ret < 0)
 177                return ret;
 178
 179        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 180        case SND_SOC_DAIFMT_NB_NF:
 181                regval = ADAU7118_LRCLK_BCLK_POL(0);
 182                break;
 183        case SND_SOC_DAIFMT_NB_IF:
 184                regval = ADAU7118_LRCLK_BCLK_POL(2);
 185                break;
 186        case SND_SOC_DAIFMT_IB_NF:
 187                regval = ADAU7118_LRCLK_BCLK_POL(1);
 188                break;
 189        case SND_SOC_DAIFMT_IB_IF:
 190                regval = ADAU7118_LRCLK_BCLK_POL(3);
 191                break;
 192        default:
 193                dev_err(st->dev, "Invalid Inv mask %d",
 194                        fmt & SND_SOC_DAIFMT_INV_MASK);
 195                return -EINVAL;
 196        }
 197
 198        ret = snd_soc_component_update_bits(dai->component,
 199                                            ADAU7118_REG_SPT_CTRL2,
 200                                            ADAU7118_LRCLK_BCLK_POL_MASK,
 201                                            regval);
 202        if (ret < 0)
 203                return ret;
 204
 205        return 0;
 206}
 207
 208static int adau7118_set_tristate(struct snd_soc_dai *dai, int tristate)
 209{
 210        struct adau7118_data *st =
 211                snd_soc_component_get_drvdata(dai->component);
 212        int ret;
 213
 214        dev_dbg(st->dev, "Set tristate, %d\n", tristate);
 215
 216        ret = snd_soc_component_update_bits(dai->component,
 217                                            ADAU7118_REG_SPT_CTRL1,
 218                                            ADAU7118_TRISTATE_MASK,
 219                                            ADAU7118_TRISTATE(tristate));
 220        if (ret < 0)
 221                return ret;
 222
 223        return 0;
 224}
 225
 226static int adau7118_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 227                                 unsigned int rx_mask, int slots,
 228                                 int slot_width)
 229{
 230        struct adau7118_data *st =
 231                snd_soc_component_get_drvdata(dai->component);
 232        int ret = 0;
 233        u32 regval;
 234
 235        dev_dbg(st->dev, "Set tdm, slots:%d width:%d\n", slots, slot_width);
 236
 237        switch (slot_width) {
 238        case 32:
 239                regval = ADAU7118_SLOT_WIDTH(0);
 240                break;
 241        case 24:
 242                regval = ADAU7118_SLOT_WIDTH(2);
 243                break;
 244        case 16:
 245                regval = ADAU7118_SLOT_WIDTH(1);
 246                break;
 247        default:
 248                dev_err(st->dev, "Invalid slot width:%d\n", slot_width);
 249                return -EINVAL;
 250        }
 251
 252        ret = snd_soc_component_update_bits(dai->component,
 253                                            ADAU7118_REG_SPT_CTRL1,
 254                                            ADAU7118_SLOT_WIDTH_MASK, regval);
 255        if (ret < 0)
 256                return ret;
 257
 258        st->slot_width = slot_width;
 259        st->slots = slots;
 260
 261        return 0;
 262}
 263
 264static int adau7118_hw_params(struct snd_pcm_substream *substream,
 265                              struct snd_pcm_hw_params *params,
 266                              struct snd_soc_dai *dai)
 267{
 268        struct adau7118_data *st =
 269                snd_soc_component_get_drvdata(dai->component);
 270        u32 data_width = params_width(params), slots_width;
 271        int ret;
 272        u32 regval;
 273
 274        if (!st->slots) {
 275                /* set stereo mode */
 276                ret = snd_soc_component_update_bits(dai->component,
 277                                                    ADAU7118_REG_SPT_CTRL1,
 278                                                    ADAU7118_SAI_MODE_MASK,
 279                                                    ADAU7118_SAI_MODE(0));
 280                if (ret < 0)
 281                        return ret;
 282
 283                slots_width = 32;
 284        } else {
 285                slots_width = st->slot_width;
 286        }
 287
 288        if (data_width > slots_width) {
 289                dev_err(st->dev, "Invalid data_width:%d, slots_width:%d",
 290                        data_width, slots_width);
 291                return -EINVAL;
 292        }
 293
 294        if (st->right_j) {
 295                switch (slots_width - data_width) {
 296                case 8:
 297                        /* delay bclck by 8 */
 298                        regval = ADAU7118_DATA_FMT(2);
 299                        break;
 300                case 12:
 301                        /* delay bclck by 12 */
 302                        regval = ADAU7118_DATA_FMT(3);
 303                        break;
 304                case 16:
 305                        /* delay bclck by 16 */
 306                        regval = ADAU7118_DATA_FMT(4);
 307                        break;
 308                default:
 309                        dev_err(st->dev,
 310                                "Cannot set right_j setting, slot_w:%d, data_w:%d\n",
 311                                        slots_width, data_width);
 312                        return -EINVAL;
 313                }
 314
 315                ret = snd_soc_component_update_bits(dai->component,
 316                                                    ADAU7118_REG_SPT_CTRL1,
 317                                                    ADAU7118_DATA_FMT_MASK,
 318                                                    regval);
 319                if (ret < 0)
 320                        return ret;
 321        }
 322
 323        return 0;
 324}
 325
 326static int adau7118_set_bias_level(struct snd_soc_component *component,
 327                                   enum snd_soc_bias_level level)
 328{
 329        struct adau7118_data *st = snd_soc_component_get_drvdata(component);
 330        int ret = 0;
 331
 332        dev_dbg(st->dev, "Set bias level %d\n", level);
 333
 334        switch (level) {
 335        case SND_SOC_BIAS_ON:
 336        case SND_SOC_BIAS_PREPARE:
 337                break;
 338
 339        case SND_SOC_BIAS_STANDBY:
 340                if (snd_soc_component_get_bias_level(component) ==
 341                                                        SND_SOC_BIAS_OFF) {
 342                        /* power on */
 343                        ret = regulator_enable(st->iovdd);
 344                        if (ret)
 345                                return ret;
 346
 347                        /* there's no timing constraints before enabling dvdd */
 348                        ret = regulator_enable(st->dvdd);
 349                        if (ret) {
 350                                regulator_disable(st->iovdd);
 351                                return ret;
 352                        }
 353
 354                        if (st->hw_mode)
 355                                return 0;
 356
 357                        regcache_cache_only(st->map, false);
 358                        /* sync cache */
 359                        ret = snd_soc_component_cache_sync(component);
 360                }
 361                break;
 362        case SND_SOC_BIAS_OFF:
 363                /* power off */
 364                ret = regulator_disable(st->dvdd);
 365                if (ret)
 366                        return ret;
 367
 368                ret = regulator_disable(st->iovdd);
 369                if (ret)
 370                        return ret;
 371
 372                if (st->hw_mode)
 373                        return 0;
 374
 375                /* cache only */
 376                regcache_mark_dirty(st->map);
 377                regcache_cache_only(st->map, true);
 378
 379                break;
 380        }
 381
 382        return ret;
 383}
 384
 385static int adau7118_component_probe(struct snd_soc_component *component)
 386{
 387        struct adau7118_data *st = snd_soc_component_get_drvdata(component);
 388        struct snd_soc_dapm_context *dapm =
 389                                        snd_soc_component_get_dapm(component);
 390        int ret = 0;
 391
 392        if (st->hw_mode) {
 393                ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw,
 394                                        ARRAY_SIZE(adau7118_widgets_hw));
 395                if (ret)
 396                        return ret;
 397
 398                ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw,
 399                                              ARRAY_SIZE(adau7118_routes_hw));
 400        } else {
 401                snd_soc_component_init_regmap(component, st->map);
 402                ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw,
 403                                        ARRAY_SIZE(adau7118_widgets_sw));
 404                if (ret)
 405                        return ret;
 406
 407                ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw,
 408                                              ARRAY_SIZE(adau7118_routes_sw));
 409        }
 410
 411        return ret;
 412}
 413
 414static const struct snd_soc_dai_ops adau7118_ops = {
 415        .hw_params = adau7118_hw_params,
 416        .set_channel_map = adau7118_set_channel_map,
 417        .set_fmt = adau7118_set_fmt,
 418        .set_tdm_slot = adau7118_set_tdm_slot,
 419        .set_tristate = adau7118_set_tristate,
 420};
 421
 422static struct snd_soc_dai_driver adau7118_dai = {
 423        .name = "adau7118-hifi-capture",
 424        .capture = {
 425                .stream_name = "Capture",
 426                .channels_min = 1,
 427                .channels_max = 8,
 428                .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
 429                        SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE |
 430                        SNDRV_PCM_FMTBIT_S24_3LE,
 431                .rates = SNDRV_PCM_RATE_CONTINUOUS,
 432                .rate_min = 4000,
 433                .rate_max = 192000,
 434                .sig_bits = 24,
 435        },
 436};
 437
 438static const struct snd_soc_component_driver adau7118_component_driver = {
 439        .probe                  = adau7118_component_probe,
 440        .set_bias_level         = adau7118_set_bias_level,
 441        .dapm_widgets           = adau7118_widgets,
 442        .num_dapm_widgets       = ARRAY_SIZE(adau7118_widgets),
 443        .use_pmdown_time        = 1,
 444        .endianness             = 1,
 445        .non_legacy_dai_naming  = 1,
 446};
 447
 448static void adau7118_regulator_disable(void *data)
 449{
 450        struct adau7118_data *st = data;
 451        int ret;
 452        /*
 453         * If we fail to disable DVDD, don't bother in trying IOVDD. We
 454         * actually don't want to be left in the situation where DVDD
 455         * is enabled and IOVDD is disabled.
 456         */
 457        ret = regulator_disable(st->dvdd);
 458        if (ret)
 459                return;
 460
 461        regulator_disable(st->iovdd);
 462}
 463
 464static int adau7118_regulator_setup(struct adau7118_data *st)
 465{
 466        st->iovdd = devm_regulator_get(st->dev, "iovdd");
 467        if (IS_ERR(st->iovdd)) {
 468                dev_err(st->dev, "Could not get iovdd: %ld\n",
 469                        PTR_ERR(st->iovdd));
 470                return PTR_ERR(st->iovdd);
 471        }
 472
 473        st->dvdd = devm_regulator_get(st->dev, "dvdd");
 474        if (IS_ERR(st->dvdd)) {
 475                dev_err(st->dev, "Could not get dvdd: %ld\n",
 476                        PTR_ERR(st->dvdd));
 477                return PTR_ERR(st->dvdd);
 478        }
 479        /* just assume the device is in reset */
 480        if (!st->hw_mode) {
 481                regcache_mark_dirty(st->map);
 482                regcache_cache_only(st->map, true);
 483        }
 484
 485        return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
 486                                        st);
 487}
 488
 489static int adau7118_parset_dt(const struct adau7118_data *st)
 490{
 491        int ret;
 492        u32 dec_ratio = 0;
 493        /* 4 inputs */
 494        u32 clk_map[4], regval;
 495
 496        if (st->hw_mode)
 497                return 0;
 498
 499        ret = device_property_read_u32(st->dev, "adi,decimation-ratio",
 500                                       &dec_ratio);
 501        if (!ret) {
 502                switch (dec_ratio) {
 503                case 64:
 504                        regval = ADAU7118_DEC_RATIO(0);
 505                        break;
 506                case 32:
 507                        regval = ADAU7118_DEC_RATIO(1);
 508                        break;
 509                case 16:
 510                        regval = ADAU7118_DEC_RATIO(2);
 511                        break;
 512                default:
 513                        dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio);
 514                        return -EINVAL;
 515                }
 516
 517                ret = regmap_update_bits(st->map,
 518                                         ADAU7118_REG_DEC_RATIO_CLK_MAP,
 519                                         ADAU7118_DEC_RATIO_MASK, regval);
 520                if (ret)
 521                        return ret;
 522        }
 523
 524        ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map",
 525                                             clk_map, ARRAY_SIZE(clk_map));
 526        if (!ret) {
 527                int pdm;
 528                u32 _clk_map = 0;
 529
 530                for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++)
 531                        _clk_map |= (clk_map[pdm] << (pdm + 4));
 532
 533                ret = regmap_update_bits(st->map,
 534                                         ADAU7118_REG_DEC_RATIO_CLK_MAP,
 535                                         ADAU7118_CLK_MAP_MASK, _clk_map);
 536                if (ret)
 537                        return ret;
 538        }
 539
 540        return 0;
 541}
 542
 543int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode)
 544{
 545        struct adau7118_data *st;
 546        int ret;
 547
 548        st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
 549        if (!st)
 550                return -ENOMEM;
 551
 552        st->dev = dev;
 553        st->hw_mode = hw_mode;
 554        dev_set_drvdata(dev, st);
 555
 556        if (!hw_mode) {
 557                st->map = map;
 558                adau7118_dai.ops = &adau7118_ops;
 559                /*
 560                 * Perform a full soft reset. This will set all register's
 561                 * with their reset values.
 562                 */
 563                ret = regmap_update_bits(map, ADAU7118_REG_RESET,
 564                                         ADAU7118_FULL_SOFT_R_MASK,
 565                                         ADAU7118_FULL_SOFT_R(1));
 566                if (ret)
 567                        return ret;
 568        }
 569
 570        ret = adau7118_parset_dt(st);
 571        if (ret)
 572                return ret;
 573
 574        ret = adau7118_regulator_setup(st);
 575        if (ret)
 576                return ret;
 577
 578        return devm_snd_soc_register_component(dev,
 579                                               &adau7118_component_driver,
 580                                               &adau7118_dai, 1);
 581}
 582EXPORT_SYMBOL_GPL(adau7118_probe);
 583
 584MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
 585MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver");
 586MODULE_LICENSE("GPL");
 587