linux/sound/soc/tegra/tegra_i2s.c
<<
>>
Prefs
   1/*
   2 * tegra_i2s.c - Tegra I2S driver
   3 *
   4 * Author: Stephen Warren <swarren@nvidia.com>
   5 * Copyright (C) 2010 - NVIDIA, Inc.
   6 *
   7 * Based on code copyright/by:
   8 *
   9 * Copyright (c) 2009-2010, NVIDIA Corporation.
  10 * Scott Peterson <speterson@nvidia.com>
  11 *
  12 * Copyright (C) 2010 Google, Inc.
  13 * Iliyan Malchev <malchev@google.com>
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License
  17 * version 2 as published by the Free Software Foundation.
  18 *
  19 * This program is distributed in the hope that it will be useful, but
  20 * WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  22 * General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, write to the Free Software
  26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  27 * 02110-1301 USA
  28 *
  29 */
  30
  31#include <linux/clk.h>
  32#include <linux/module.h>
  33#include <linux/debugfs.h>
  34#include <linux/device.h>
  35#include <linux/platform_device.h>
  36#include <linux/seq_file.h>
  37#include <linux/slab.h>
  38#include <linux/io.h>
  39#include <mach/iomap.h>
  40#include <sound/core.h>
  41#include <sound/pcm.h>
  42#include <sound/pcm_params.h>
  43#include <sound/soc.h>
  44
  45#include "tegra_das.h"
  46#include "tegra_i2s.h"
  47
  48#define DRV_NAME "tegra-i2s"
  49
  50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val)
  51{
  52        __raw_writel(val, i2s->regs + reg);
  53}
  54
  55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg)
  56{
  57        return __raw_readl(i2s->regs + reg);
  58}
  59
  60#ifdef CONFIG_DEBUG_FS
  61static int tegra_i2s_show(struct seq_file *s, void *unused)
  62{
  63#define REG(r) { r, #r }
  64        static const struct {
  65                int offset;
  66                const char *name;
  67        } regs[] = {
  68                REG(TEGRA_I2S_CTRL),
  69                REG(TEGRA_I2S_STATUS),
  70                REG(TEGRA_I2S_TIMING),
  71                REG(TEGRA_I2S_FIFO_SCR),
  72                REG(TEGRA_I2S_PCM_CTRL),
  73                REG(TEGRA_I2S_NW_CTRL),
  74                REG(TEGRA_I2S_TDM_CTRL),
  75                REG(TEGRA_I2S_TDM_TX_RX_CTRL),
  76        };
  77#undef REG
  78
  79        struct tegra_i2s *i2s = s->private;
  80        int i;
  81
  82        for (i = 0; i < ARRAY_SIZE(regs); i++) {
  83                u32 val = tegra_i2s_read(i2s, regs[i].offset);
  84                seq_printf(s, "%s = %08x\n", regs[i].name, val);
  85        }
  86
  87        return 0;
  88}
  89
  90static int tegra_i2s_debug_open(struct inode *inode, struct file *file)
  91{
  92        return single_open(file, tegra_i2s_show, inode->i_private);
  93}
  94
  95static const struct file_operations tegra_i2s_debug_fops = {
  96        .open    = tegra_i2s_debug_open,
  97        .read    = seq_read,
  98        .llseek  = seq_lseek,
  99        .release = single_release,
 100};
 101
 102static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
 103{
 104        char name[] = DRV_NAME ".0";
 105
 106        snprintf(name, sizeof(name), DRV_NAME".%1d", id);
 107        i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
 108                                                i2s, &tegra_i2s_debug_fops);
 109}
 110
 111static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
 112{
 113        if (i2s->debug)
 114                debugfs_remove(i2s->debug);
 115}
 116#else
 117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
 118{
 119}
 120
 121static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
 122{
 123}
 124#endif
 125
 126static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
 127                                unsigned int fmt)
 128{
 129        struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 130
 131        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 132        case SND_SOC_DAIFMT_NB_NF:
 133                break;
 134        default:
 135                return -EINVAL;
 136        }
 137
 138        i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE;
 139        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 140        case SND_SOC_DAIFMT_CBS_CFS:
 141                i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE;
 142                break;
 143        case SND_SOC_DAIFMT_CBM_CFM:
 144                break;
 145        default:
 146                return -EINVAL;
 147        }
 148
 149        i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK | 
 150                                TEGRA_I2S_CTRL_LRCK_MASK);
 151        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 152        case SND_SOC_DAIFMT_DSP_A:
 153                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
 154                i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
 155                break;
 156        case SND_SOC_DAIFMT_DSP_B:
 157                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
 158                i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW;
 159                break;
 160        case SND_SOC_DAIFMT_I2S:
 161                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S;
 162                i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
 163                break;
 164        case SND_SOC_DAIFMT_RIGHT_J:
 165                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM;
 166                i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
 167                break;
 168        case SND_SOC_DAIFMT_LEFT_J:
 169                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM;
 170                i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
 171                break;
 172        default:
 173                return -EINVAL;
 174        }
 175
 176        return 0;
 177}
 178
 179static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
 180                                struct snd_pcm_hw_params *params,
 181                                struct snd_soc_dai *dai)
 182{
 183        struct device *dev = substream->pcm->card->dev;
 184        struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 185        u32 reg;
 186        int ret, sample_size, srate, i2sclock, bitcnt;
 187
 188        i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK;
 189        switch (params_format(params)) {
 190        case SNDRV_PCM_FORMAT_S16_LE:
 191                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16;
 192                sample_size = 16;
 193                break;
 194        case SNDRV_PCM_FORMAT_S24_LE:
 195                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24;
 196                sample_size = 24;
 197                break;
 198        case SNDRV_PCM_FORMAT_S32_LE:
 199                i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32;
 200                sample_size = 32;
 201                break;
 202        default:
 203                return -EINVAL;
 204        }
 205
 206        srate = params_rate(params);
 207
 208        /* Final "* 2" required by Tegra hardware */
 209        i2sclock = srate * params_channels(params) * sample_size * 2;
 210
 211        ret = clk_set_rate(i2s->clk_i2s, i2sclock);
 212        if (ret) {
 213                dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
 214                return ret;
 215        }
 216
 217        bitcnt = (i2sclock / (2 * srate)) - 1;
 218        if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
 219                return -EINVAL;
 220        reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
 221
 222        if (i2sclock % (2 * srate))
 223                reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
 224
 225        tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
 226
 227        tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
 228                TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
 229                TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
 230
 231        return 0;
 232}
 233
 234static void tegra_i2s_start_playback(struct tegra_i2s *i2s)
 235{
 236        i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE;
 237        tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
 238}
 239
 240static void tegra_i2s_stop_playback(struct tegra_i2s *i2s)
 241{
 242        i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE;
 243        tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
 244}
 245
 246static void tegra_i2s_start_capture(struct tegra_i2s *i2s)
 247{
 248        i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE;
 249        tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
 250}
 251
 252static void tegra_i2s_stop_capture(struct tegra_i2s *i2s)
 253{
 254        i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE;
 255        tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
 256}
 257
 258static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 259                                struct snd_soc_dai *dai)
 260{
 261        struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 262
 263        switch (cmd) {
 264        case SNDRV_PCM_TRIGGER_START:
 265        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 266        case SNDRV_PCM_TRIGGER_RESUME:
 267                if (!i2s->clk_refs)
 268                        clk_enable(i2s->clk_i2s);
 269                i2s->clk_refs++;
 270                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 271                        tegra_i2s_start_playback(i2s);
 272                else
 273                        tegra_i2s_start_capture(i2s);
 274                break;
 275        case SNDRV_PCM_TRIGGER_STOP:
 276        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 277        case SNDRV_PCM_TRIGGER_SUSPEND:
 278                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 279                        tegra_i2s_stop_playback(i2s);
 280                else
 281                        tegra_i2s_stop_capture(i2s);
 282                i2s->clk_refs--;
 283                if (!i2s->clk_refs)
 284                        clk_disable(i2s->clk_i2s);
 285                break;
 286        default:
 287                return -EINVAL;
 288        }
 289
 290        return 0;
 291}
 292
 293static int tegra_i2s_probe(struct snd_soc_dai *dai)
 294{
 295        struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai);
 296
 297        dai->capture_dma_data = &i2s->capture_dma_data;
 298        dai->playback_dma_data = &i2s->playback_dma_data;
 299
 300        return 0;
 301}
 302
 303static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
 304        .set_fmt        = tegra_i2s_set_fmt,
 305        .hw_params      = tegra_i2s_hw_params,
 306        .trigger        = tegra_i2s_trigger,
 307};
 308
 309struct snd_soc_dai_driver tegra_i2s_dai[] = {
 310        {
 311                .name = DRV_NAME ".0",
 312                .probe = tegra_i2s_probe,
 313                .playback = {
 314                        .channels_min = 2,
 315                        .channels_max = 2,
 316                        .rates = SNDRV_PCM_RATE_8000_96000,
 317                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 318                },
 319                .capture = {
 320                        .channels_min = 2,
 321                        .channels_max = 2,
 322                        .rates = SNDRV_PCM_RATE_8000_96000,
 323                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 324                },
 325                .ops = &tegra_i2s_dai_ops,
 326                .symmetric_rates = 1,
 327        },
 328        {
 329                .name = DRV_NAME ".1",
 330                .probe = tegra_i2s_probe,
 331                .playback = {
 332                        .channels_min = 2,
 333                        .channels_max = 2,
 334                        .rates = SNDRV_PCM_RATE_8000_96000,
 335                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 336                },
 337                .capture = {
 338                        .channels_min = 2,
 339                        .channels_max = 2,
 340                        .rates = SNDRV_PCM_RATE_8000_96000,
 341                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 342                },
 343                .ops = &tegra_i2s_dai_ops,
 344                .symmetric_rates = 1,
 345        },
 346};
 347
 348static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
 349{
 350        struct tegra_i2s * i2s;
 351        char clk_name[12]; /* tegra-i2s.0 */
 352        struct resource *mem, *memregion, *dmareq;
 353        int ret;
 354
 355        if ((pdev->id < 0) ||
 356                (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
 357                dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
 358                return -EINVAL;
 359        }
 360
 361        /*
 362         * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
 363         * 1:1 mapping between audio controllers and audio ports.
 364         */
 365        ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
 366                                        TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
 367        if (ret) {
 368                dev_err(&pdev->dev, "Can't set up DAP connection\n");
 369                return ret;
 370        }
 371        ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
 372                                        TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
 373        if (ret) {
 374                dev_err(&pdev->dev, "Can't set up DAC connection\n");
 375                return ret;
 376        }
 377
 378        i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
 379        if (!i2s) {
 380                dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
 381                ret = -ENOMEM;
 382                goto exit;
 383        }
 384        dev_set_drvdata(&pdev->dev, i2s);
 385
 386        snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
 387        i2s->clk_i2s = clk_get_sys(clk_name, NULL);
 388        if (IS_ERR(i2s->clk_i2s)) {
 389                dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
 390                ret = PTR_ERR(i2s->clk_i2s);
 391                goto err_free;
 392        }
 393
 394        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 395        if (!mem) {
 396                dev_err(&pdev->dev, "No memory resource\n");
 397                ret = -ENODEV;
 398                goto err_clk_put;
 399        }
 400
 401        dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 402        if (!dmareq) {
 403                dev_err(&pdev->dev, "No DMA resource\n");
 404                ret = -ENODEV;
 405                goto err_clk_put;
 406        }
 407
 408        memregion = request_mem_region(mem->start, resource_size(mem),
 409                                        DRV_NAME);
 410        if (!memregion) {
 411                dev_err(&pdev->dev, "Memory region already claimed\n");
 412                ret = -EBUSY;
 413                goto err_clk_put;
 414        }
 415
 416        i2s->regs = ioremap(mem->start, resource_size(mem));
 417        if (!i2s->regs) {
 418                dev_err(&pdev->dev, "ioremap failed\n");
 419                ret = -ENOMEM;
 420                goto err_release;
 421        }
 422
 423        i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
 424        i2s->capture_dma_data.wrap = 4;
 425        i2s->capture_dma_data.width = 32;
 426        i2s->capture_dma_data.req_sel = dmareq->start;
 427
 428        i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
 429        i2s->playback_dma_data.wrap = 4;
 430        i2s->playback_dma_data.width = 32;
 431        i2s->playback_dma_data.req_sel = dmareq->start;
 432
 433        i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
 434
 435        ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
 436        if (ret) {
 437                dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
 438                ret = -ENOMEM;
 439                goto err_unmap;
 440        }
 441
 442        tegra_i2s_debug_add(i2s, pdev->id);
 443
 444        return 0;
 445
 446err_unmap:
 447        iounmap(i2s->regs);
 448err_release:
 449        release_mem_region(mem->start, resource_size(mem));
 450err_clk_put:
 451        clk_put(i2s->clk_i2s);
 452err_free:
 453        kfree(i2s);
 454exit:
 455        return ret;
 456}
 457
 458static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
 459{
 460        struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
 461        struct resource *res;
 462
 463        snd_soc_unregister_dai(&pdev->dev);
 464
 465        tegra_i2s_debug_remove(i2s);
 466
 467        iounmap(i2s->regs);
 468
 469        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 470        release_mem_region(res->start, resource_size(res));
 471
 472        clk_put(i2s->clk_i2s);
 473
 474        kfree(i2s);
 475
 476        return 0;
 477}
 478
 479static struct platform_driver tegra_i2s_driver = {
 480        .driver = {
 481                .name = DRV_NAME,
 482                .owner = THIS_MODULE,
 483        },
 484        .probe = tegra_i2s_platform_probe,
 485        .remove = __devexit_p(tegra_i2s_platform_remove),
 486};
 487
 488static int __init snd_tegra_i2s_init(void)
 489{
 490        return platform_driver_register(&tegra_i2s_driver);
 491}
 492module_init(snd_tegra_i2s_init);
 493
 494static void __exit snd_tegra_i2s_exit(void)
 495{
 496        platform_driver_unregister(&tegra_i2s_driver);
 497}
 498module_exit(snd_tegra_i2s_exit);
 499
 500MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 501MODULE_DESCRIPTION("Tegra I2S ASoC driver");
 502MODULE_LICENSE("GPL");
 503MODULE_ALIAS("platform:" DRV_NAME);
 504