root/sound/soc/qcom/storm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. storm_ops_hw_params
  2. storm_parse_of
  3. storm_platform_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
   4  *
   5  * storm.c -- ALSA SoC machine driver for QTi ipq806x-based Storm board
   6  */
   7 
   8 #include <linux/device.h>
   9 #include <linux/module.h>
  10 #include <linux/of.h>
  11 #include <linux/mod_devicetable.h>
  12 #include <linux/platform_device.h>
  13 #include <sound/pcm.h>
  14 #include <sound/pcm_params.h>
  15 #include <sound/soc.h>
  16 
  17 #define STORM_SYSCLK_MULT                       4
  18 
  19 static int storm_ops_hw_params(struct snd_pcm_substream *substream,
  20                 struct snd_pcm_hw_params *params)
  21 {
  22         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
  23         struct snd_soc_card *card = soc_runtime->card;
  24         snd_pcm_format_t format = params_format(params);
  25         unsigned int rate = params_rate(params);
  26         unsigned int sysclk_freq;
  27         int bitwidth, ret;
  28 
  29         bitwidth = snd_pcm_format_width(format);
  30         if (bitwidth < 0) {
  31                 dev_err(card->dev, "invalid bit width given: %d\n", bitwidth);
  32                 return bitwidth;
  33         }
  34 
  35         /*
  36          * as the CPU DAI is the I2S bus master and no system clock is needed by
  37          * the MAX98357a DAC, simply set the system clock to be a constant
  38          * multiple of the bit clock for the clock divider
  39          */
  40         sysclk_freq = rate * bitwidth * 2 * STORM_SYSCLK_MULT;
  41 
  42         ret = snd_soc_dai_set_sysclk(soc_runtime->cpu_dai, 0, sysclk_freq, 0);
  43         if (ret) {
  44                 dev_err(card->dev, "error setting sysclk to %u: %d\n",
  45                         sysclk_freq, ret);
  46                 return ret;
  47         }
  48 
  49         return 0;
  50 }
  51 
  52 static const struct snd_soc_ops storm_soc_ops = {
  53         .hw_params      = storm_ops_hw_params,
  54 };
  55 
  56 SND_SOC_DAILINK_DEFS(hifi,
  57         DAILINK_COMP_ARRAY(COMP_EMPTY()),
  58         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
  59         DAILINK_COMP_ARRAY(COMP_EMPTY()));
  60 
  61 static struct snd_soc_dai_link storm_dai_link = {
  62         .name           = "Primary",
  63         .stream_name    = "Primary",
  64         .ops            = &storm_soc_ops,
  65         SND_SOC_DAILINK_REG(hifi),
  66 };
  67 
  68 static int storm_parse_of(struct snd_soc_card *card)
  69 {
  70         struct snd_soc_dai_link *dai_link = card->dai_link;
  71         struct device_node *np = card->dev->of_node;
  72 
  73         dai_link->cpus->of_node = of_parse_phandle(np, "cpu", 0);
  74         if (!dai_link->cpus->of_node) {
  75                 dev_err(card->dev, "error getting cpu phandle\n");
  76                 return -EINVAL;
  77         }
  78         dai_link->platforms->of_node = dai_link->cpus->of_node;
  79 
  80         dai_link->codecs->of_node = of_parse_phandle(np, "codec", 0);
  81         if (!dai_link->codecs->of_node) {
  82                 dev_err(card->dev, "error getting codec phandle\n");
  83                 return -EINVAL;
  84         }
  85 
  86         return 0;
  87 }
  88 
  89 static int storm_platform_probe(struct platform_device *pdev)
  90 {
  91         struct snd_soc_card *card;
  92         int ret;
  93 
  94         card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
  95         if (!card)
  96                 return -ENOMEM;
  97 
  98         card->dev = &pdev->dev;
  99 
 100         ret = snd_soc_of_parse_card_name(card, "qcom,model");
 101         if (ret) {
 102                 dev_err(&pdev->dev, "error parsing card name: %d\n", ret);
 103                 return ret;
 104         }
 105 
 106         card->dai_link  = &storm_dai_link;
 107         card->num_links = 1;
 108 
 109         ret = storm_parse_of(card);
 110         if (ret) {
 111                 dev_err(&pdev->dev, "error resolving dai links: %d\n", ret);
 112                 return ret;
 113         }
 114 
 115         ret = devm_snd_soc_register_card(&pdev->dev, card);
 116         if (ret)
 117                 dev_err(&pdev->dev, "error registering soundcard: %d\n", ret);
 118 
 119         return ret;
 120 
 121 }
 122 
 123 #ifdef CONFIG_OF
 124 static const struct of_device_id storm_device_id[]  = {
 125         { .compatible = "google,storm-audio" },
 126         {},
 127 };
 128 MODULE_DEVICE_TABLE(of, storm_device_id);
 129 #endif
 130 
 131 static struct platform_driver storm_platform_driver = {
 132         .driver = {
 133                 .name = "storm-audio",
 134                 .of_match_table =
 135                         of_match_ptr(storm_device_id),
 136         },
 137         .probe = storm_platform_probe,
 138 };
 139 module_platform_driver(storm_platform_driver);
 140 
 141 MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
 142 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */