uboot/drivers/sound/tegra_sound.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2018 Google, LLC
   4 * Written by Simon Glass <sjg@chromium.org>
   5 */
   6
   7#define LOG_CATEGORY UCLASS_I2S
   8
   9#include <common.h>
  10#include <audio_codec.h>
  11#include <dm.h>
  12#include <i2s.h>
  13#include <log.h>
  14#include <misc.h>
  15#include <sound.h>
  16#include <asm/gpio.h>
  17#include "tegra_i2s_priv.h"
  18
  19static int tegra_sound_setup(struct udevice *dev)
  20{
  21        struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
  22        struct i2s_uc_priv *i2c_priv = dev_get_uclass_priv(uc_priv->i2s);
  23        int ret;
  24
  25        if (uc_priv->setup_done)
  26                return -EALREADY;
  27        ret = audio_codec_set_params(uc_priv->codec, i2c_priv->id,
  28                                     i2c_priv->samplingrate,
  29                                     i2c_priv->samplingrate * i2c_priv->rfs,
  30                                     i2c_priv->bitspersample,
  31                                     i2c_priv->channels);
  32        if (ret)
  33                return ret;
  34        uc_priv->setup_done = true;
  35
  36        return 0;
  37}
  38
  39static int tegra_sound_play(struct udevice *dev, void *data, uint data_size)
  40{
  41        struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
  42
  43        return i2s_tx_data(uc_priv->i2s, data, data_size);
  44}
  45
  46static int tegra_sound_probe(struct udevice *dev)
  47{
  48        struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
  49        struct gpio_desc en_gpio;
  50        struct udevice *ahub;
  51        int ret;
  52
  53        ret = gpio_request_by_name(dev, "codec-enable-gpio", 0, &en_gpio,
  54                                   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
  55
  56        ret = uclass_get_device_by_phandle(UCLASS_AUDIO_CODEC, dev,
  57                                           "nvidia,audio-codec",
  58                                           &uc_priv->codec);
  59        if (ret) {
  60                log_debug("Failed to probe audio codec\n");
  61                return ret;
  62        }
  63        ret = uclass_get_device_by_phandle(UCLASS_I2S, dev,
  64                                           "nvidia,i2s-controller",
  65                                           &uc_priv->i2s);
  66        if (ret) {
  67                log_debug("Cannot find i2s: %d\n", ret);
  68                return ret;
  69        }
  70
  71        /* Set up the audio hub, telling it the currect i2s to use */
  72        ahub = dev_get_parent(uc_priv->i2s);
  73        ret = misc_ioctl(ahub, AHUB_MISCOP_SET_I2S, &uc_priv->i2s);
  74        if (ret) {
  75                log_debug("Cannot set i2c: %d\n", ret);
  76                return ret;
  77        }
  78
  79        log_debug("Probed sound '%s' with codec '%s' and i2s '%s'\n", dev->name,
  80                  uc_priv->codec->name, uc_priv->i2s->name);
  81
  82        return 0;
  83}
  84
  85static const struct sound_ops tegra_sound_ops = {
  86        .setup  = tegra_sound_setup,
  87        .play   = tegra_sound_play,
  88};
  89
  90static const struct udevice_id tegra_sound_ids[] = {
  91        { .compatible = "nvidia,tegra-audio-max98090-nyan-big" },
  92        { }
  93};
  94
  95U_BOOT_DRIVER(tegra_sound) = {
  96        .name           = "tegra_sound",
  97        .id             = UCLASS_SOUND,
  98        .of_match       = tegra_sound_ids,
  99        .probe          = tegra_sound_probe,
 100        .ops            = &tegra_sound_ops,
 101};
 102