linux/sound/soc/sirf/sirf-audio.c
<<
>>
Prefs
   1/*
   2 * SiRF audio card driver
   3 *
   4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
   5 *
   6 * Licensed under GPLv2 or later.
   7 */
   8
   9#include <linux/platform_device.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/gpio.h>
  13#include <linux/of_gpio.h>
  14#include <sound/core.h>
  15#include <sound/pcm.h>
  16#include <sound/soc.h>
  17
  18struct sirf_audio_card {
  19        unsigned int            gpio_hp_pa;
  20        unsigned int            gpio_spk_pa;
  21};
  22
  23static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w,
  24                                struct snd_kcontrol *ctrl, int event)
  25{
  26        struct snd_soc_dapm_context *dapm = w->dapm;
  27        struct snd_soc_card *card = dapm->card;
  28        struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
  29        int on = !SND_SOC_DAPM_EVENT_OFF(event);
  30        if (gpio_is_valid(sirf_audio_card->gpio_hp_pa))
  31                gpio_set_value(sirf_audio_card->gpio_hp_pa, on);
  32        return 0;
  33}
  34
  35static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w,
  36                                struct snd_kcontrol *ctrl, int event)
  37{
  38        struct snd_soc_dapm_context *dapm = w->dapm;
  39        struct snd_soc_card *card = dapm->card;
  40        struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
  41        int on = !SND_SOC_DAPM_EVENT_OFF(event);
  42
  43        if (gpio_is_valid(sirf_audio_card->gpio_spk_pa))
  44                gpio_set_value(sirf_audio_card->gpio_spk_pa, on);
  45
  46        return 0;
  47}
  48static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = {
  49        SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event),
  50        SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event),
  51        SND_SOC_DAPM_MIC("Ext Mic", NULL),
  52};
  53
  54static const struct snd_soc_dapm_route intercon[] = {
  55        {"Hp", NULL, "HPOUTL"},
  56        {"Hp", NULL, "HPOUTR"},
  57        {"Ext Spk", NULL, "SPKOUT"},
  58        {"MICIN1", NULL, "Mic Bias"},
  59        {"Mic Bias", NULL, "Ext Mic"},
  60};
  61
  62/* Digital audio interface glue - connects codec <--> CPU */
  63static struct snd_soc_dai_link sirf_audio_dai_link[] = {
  64        {
  65                .name = "SiRF audio card",
  66                .stream_name = "SiRF audio HiFi",
  67                .codec_dai_name = "sirf-audio-codec",
  68        },
  69};
  70
  71/* Audio machine driver */
  72static struct snd_soc_card snd_soc_sirf_audio_card = {
  73        .name = "SiRF audio card",
  74        .owner = THIS_MODULE,
  75        .dai_link = sirf_audio_dai_link,
  76        .num_links = ARRAY_SIZE(sirf_audio_dai_link),
  77        .dapm_widgets = sirf_audio_dapm_widgets,
  78        .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets),
  79        .dapm_routes = intercon,
  80        .num_dapm_routes = ARRAY_SIZE(intercon),
  81};
  82
  83static int sirf_audio_probe(struct platform_device *pdev)
  84{
  85        struct snd_soc_card *card = &snd_soc_sirf_audio_card;
  86        struct sirf_audio_card *sirf_audio_card;
  87        int ret;
  88
  89        sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card),
  90                        GFP_KERNEL);
  91        if (sirf_audio_card == NULL)
  92                return -ENOMEM;
  93
  94        sirf_audio_dai_link[0].cpu_of_node =
  95                of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0);
  96        sirf_audio_dai_link[0].platform_of_node =
  97                of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0);
  98        sirf_audio_dai_link[0].codec_of_node =
  99                of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0);
 100        sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node,
 101                        "spk-pa-gpios", 0);
 102        sirf_audio_card->gpio_hp_pa =  of_get_named_gpio(pdev->dev.of_node,
 103                        "hp-pa-gpios", 0);
 104        if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) {
 105                ret = devm_gpio_request_one(&pdev->dev,
 106                                sirf_audio_card->gpio_spk_pa,
 107                                GPIOF_OUT_INIT_LOW, "SPA_PA_SD");
 108                if (ret) {
 109                        dev_err(&pdev->dev,
 110                                "Failed to request GPIO_%d for reset: %d\n",
 111                                sirf_audio_card->gpio_spk_pa, ret);
 112                        return ret;
 113                }
 114        }
 115        if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) {
 116                ret = devm_gpio_request_one(&pdev->dev,
 117                                sirf_audio_card->gpio_hp_pa,
 118                                GPIOF_OUT_INIT_LOW, "HP_PA_SD");
 119                if (ret) {
 120                        dev_err(&pdev->dev,
 121                                "Failed to request GPIO_%d for reset: %d\n",
 122                                sirf_audio_card->gpio_hp_pa, ret);
 123                        return ret;
 124                }
 125        }
 126
 127        card->dev = &pdev->dev;
 128        snd_soc_card_set_drvdata(card, sirf_audio_card);
 129
 130        ret = devm_snd_soc_register_card(&pdev->dev, card);
 131        if (ret)
 132                dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
 133
 134        return ret;
 135}
 136
 137static const struct of_device_id sirf_audio_of_match[] = {
 138        {.compatible = "sirf,sirf-audio-card", },
 139        { },
 140};
 141MODULE_DEVICE_TABLE(of, sirf_audio_of_match);
 142
 143static struct platform_driver sirf_audio_driver = {
 144        .driver = {
 145                .name = "sirf-audio-card",
 146                .pm = &snd_soc_pm_ops,
 147                .of_match_table = sirf_audio_of_match,
 148        },
 149        .probe = sirf_audio_probe,
 150};
 151module_platform_driver(sirf_audio_driver);
 152
 153MODULE_AUTHOR("RongJun Ying <RongJun.Ying@csr.com>");
 154MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver");
 155MODULE_LICENSE("GPL v2");
 156