~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/pxa/hx4700.c

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * SoC audio for HP iPAQ hx4700
  4  *
  5  * Copyright (c) 2009 Philipp Zabel
  6  */
  7 
  8 #include <linux/module.h>
  9 #include <linux/timer.h>
 10 #include <linux/interrupt.h>
 11 #include <linux/platform_device.h>
 12 #include <linux/delay.h>
 13 #include <linux/gpio.h>
 14 
 15 #include <sound/core.h>
 16 #include <sound/jack.h>
 17 #include <sound/pcm.h>
 18 #include <sound/pcm_params.h>
 19 #include <sound/soc.h>
 20 
 21 #include <mach/hx4700.h>
 22 #include <asm/mach-types.h>
 23 #include "pxa2xx-i2s.h"
 24 
 25 static struct snd_soc_jack hs_jack;
 26 
 27 /* Headphones jack detection DAPM pin */
 28 static struct snd_soc_jack_pin hs_jack_pin[] = {
 29         {
 30                 .pin    = "Headphone Jack",
 31                 .mask   = SND_JACK_HEADPHONE,
 32         },
 33         {
 34                 .pin    = "Speaker",
 35                 /* disable speaker when hp jack is inserted */
 36                 .mask   = SND_JACK_HEADPHONE,
 37                 .invert = 1,
 38         },
 39 };
 40 
 41 /* Headphones jack detection GPIO */
 42 static struct snd_soc_jack_gpio hs_jack_gpio = {
 43         .gpio           = GPIO75_HX4700_EARPHONE_nDET,
 44         .invert         = true,
 45         .name           = "hp-gpio",
 46         .report         = SND_JACK_HEADPHONE,
 47         .debounce_time  = 200,
 48 };
 49 
 50 /*
 51  * iPAQ hx4700 uses I2S for capture and playback.
 52  */
 53 static int hx4700_hw_params(struct snd_pcm_substream *substream,
 54                             struct snd_pcm_hw_params *params)
 55 {
 56         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 57         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
 58         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
 59         int ret = 0;
 60 
 61         /* set the I2S system clock as output */
 62         ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
 63                         SND_SOC_CLOCK_OUT);
 64         if (ret < 0)
 65                 return ret;
 66 
 67         /* inform codec driver about clock freq *
 68          * (PXA I2S always uses divider 256)    */
 69         ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
 70                         SND_SOC_CLOCK_IN);
 71         if (ret < 0)
 72                 return ret;
 73 
 74         return 0;
 75 }
 76 
 77 static const struct snd_soc_ops hx4700_ops = {
 78         .hw_params = hx4700_hw_params,
 79 };
 80 
 81 static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
 82                             struct snd_kcontrol *k, int event)
 83 {
 84         gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
 85         return 0;
 86 }
 87 
 88 static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
 89                            struct snd_kcontrol *k, int event)
 90 {
 91         gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
 92         return 0;
 93 }
 94 
 95 /* hx4700 machine dapm widgets */
 96 static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
 97         SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
 98         SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
 99         SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
100 };
101 
102 /* hx4700 machine audio_map */
103 static const struct snd_soc_dapm_route hx4700_audio_map[] = {
104 
105         /* Headphone connected to LOUT, ROUT */
106         {"Headphone Jack", NULL, "LOUT"},
107         {"Headphone Jack", NULL, "ROUT"},
108 
109         /* Speaker connected to MOUT2 */
110         {"Speaker", NULL, "MOUT2"},
111 
112         /* Microphone connected to MICIN */
113         {"MICIN", NULL, "Built-in Microphone"},
114         {"AIN", NULL, "MICOUT"},
115 };
116 
117 /*
118  * Logic for a ak4641 as connected on a HP iPAQ hx4700
119  */
120 static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
121 {
122         int err;
123 
124         /* Jack detection API stuff */
125         err = snd_soc_card_jack_new(rtd->card, "Headphone Jack",
126                                     SND_JACK_HEADPHONE, &hs_jack, hs_jack_pin,
127                                     ARRAY_SIZE(hs_jack_pin));
128         if (err)
129                 return err;
130 
131         err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
132 
133         return err;
134 }
135 
136 /* hx4700 digital audio interface glue - connects codec <--> CPU */
137 SND_SOC_DAILINK_DEFS(ak4641,
138         DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
139         DAILINK_COMP_ARRAY(COMP_CODEC("ak4641.0-0012", "ak4641-hifi")),
140         DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
141 
142 static struct snd_soc_dai_link hx4700_dai = {
143         .name = "ak4641",
144         .stream_name = "AK4641",
145         .init = hx4700_ak4641_init,
146         .dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
147                    SND_SOC_DAIFMT_CBS_CFS,
148         .ops = &hx4700_ops,
149         SND_SOC_DAILINK_REG(ak4641),
150 };
151 
152 /* hx4700 audio machine driver */
153 static struct snd_soc_card snd_soc_card_hx4700 = {
154         .name                   = "iPAQ hx4700",
155         .owner                  = THIS_MODULE,
156         .dai_link               = &hx4700_dai,
157         .num_links              = 1,
158         .dapm_widgets           = hx4700_dapm_widgets,
159         .num_dapm_widgets       = ARRAY_SIZE(hx4700_dapm_widgets),
160         .dapm_routes            = hx4700_audio_map,
161         .num_dapm_routes        = ARRAY_SIZE(hx4700_audio_map),
162         .fully_routed           = true,
163 };
164 
165 static struct gpio hx4700_audio_gpios[] = {
166         { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
167         { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
168 };
169 
170 static int hx4700_audio_probe(struct platform_device *pdev)
171 {
172         int ret;
173 
174         if (!machine_is_h4700())
175                 return -ENODEV;
176 
177         ret = gpio_request_array(hx4700_audio_gpios,
178                                 ARRAY_SIZE(hx4700_audio_gpios));
179         if (ret)
180                 return ret;
181 
182         snd_soc_card_hx4700.dev = &pdev->dev;
183         ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
184         if (ret)
185                 gpio_free_array(hx4700_audio_gpios,
186                                 ARRAY_SIZE(hx4700_audio_gpios));
187 
188         return ret;
189 }
190 
191 static int hx4700_audio_remove(struct platform_device *pdev)
192 {
193         gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
194         gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
195 
196         gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
197         return 0;
198 }
199 
200 static struct platform_driver hx4700_audio_driver = {
201         .driver = {
202                 .name = "hx4700-audio",
203                 .pm = &snd_soc_pm_ops,
204         },
205         .probe  = hx4700_audio_probe,
206         .remove = hx4700_audio_remove,
207 };
208 
209 module_platform_driver(hx4700_audio_driver);
210 
211 MODULE_AUTHOR("Philipp Zabel");
212 MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
213 MODULE_LICENSE("GPL");
214 MODULE_ALIAS("platform:hx4700-audio");
215 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp