| OLD | NEW |
| 1 /* | 1 /* |
| 2 * ASoC driver for Stretch s6105 IP camera platform | 2 * ASoC driver for Stretch s6105 IP camera platform |
| 3 * | 3 * |
| 4 * Author: Daniel Gloeckner, <dg@emlix.com> | 4 * Author: Daniel Gloeckner, <dg@emlix.com> |
| 5 * Copyright: (C) 2009 emlix GmbH <info@emlix.com> | 5 * Copyright: (C) 2009 emlix GmbH <info@emlix.com> |
| 6 * | 6 * |
| 7 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
| 8 * it under the terms of the GNU General Public License version 2 as | 8 * it under the terms of the GNU General Public License version 2 as |
| 9 * published by the Free Software Foundation. | 9 * published by the Free Software Foundation. |
| 10 */ | 10 */ |
| 11 | 11 |
| 12 #include <linux/module.h> | 12 #include <linux/module.h> |
| 13 #include <linux/moduleparam.h> | 13 #include <linux/moduleparam.h> |
| 14 #include <linux/timer.h> | 14 #include <linux/timer.h> |
| 15 #include <linux/interrupt.h> | 15 #include <linux/interrupt.h> |
| 16 #include <linux/platform_device.h> | 16 #include <linux/platform_device.h> |
| 17 #include <linux/i2c.h> | 17 #include <linux/i2c.h> |
| 18 #include <sound/core.h> | 18 #include <sound/core.h> |
| 19 #include <sound/pcm.h> | 19 #include <sound/pcm.h> |
| 20 #include <sound/soc.h> | 20 #include <sound/soc.h> |
| 21 #include <sound/soc-dapm.h> | |
| 22 | 21 |
| 23 #include <variant/dmac.h> | 22 #include <variant/dmac.h> |
| 24 | 23 |
| 25 #include "../codecs/tlv320aic3x.h" | |
| 26 #include "s6000-pcm.h" | 24 #include "s6000-pcm.h" |
| 27 #include "s6000-i2s.h" | 25 #include "s6000-i2s.h" |
| 28 | 26 |
| 29 #define S6105_CAM_CODEC_CLOCK 12288000 | 27 #define S6105_CAM_CODEC_CLOCK 12288000 |
| 30 | 28 |
| 31 static int s6105_hw_params(struct snd_pcm_substream *substream, | 29 static int s6105_hw_params(struct snd_pcm_substream *substream, |
| 32 struct snd_pcm_hw_params *params) | 30 struct snd_pcm_hw_params *params) |
| 33 { | 31 { |
| 34 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 32 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 35 struct snd_soc_dai *codec_dai = rtd->codec_dai; | 33 struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 struct snd_ctl_elem_value *ucontrol) | 98 struct snd_ctl_elem_value *ucontrol) |
| 101 { | 99 { |
| 102 ucontrol->value.enumerated.item[0] = kcontrol->private_value; | 100 ucontrol->value.enumerated.item[0] = kcontrol->private_value; |
| 103 return 0; | 101 return 0; |
| 104 } | 102 } |
| 105 | 103 |
| 106 static int output_type_put(struct snd_kcontrol *kcontrol, | 104 static int output_type_put(struct snd_kcontrol *kcontrol, |
| 107 struct snd_ctl_elem_value *ucontrol) | 105 struct snd_ctl_elem_value *ucontrol) |
| 108 { | 106 { |
| 109 struct snd_soc_codec *codec = kcontrol->private_data; | 107 struct snd_soc_codec *codec = kcontrol->private_data; |
| 108 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 110 unsigned int val = (ucontrol->value.enumerated.item[0] != 0); | 109 unsigned int val = (ucontrol->value.enumerated.item[0] != 0); |
| 111 char *differential = "Audio Out Differential"; | 110 char *differential = "Audio Out Differential"; |
| 112 char *stereo = "Audio Out Stereo"; | 111 char *stereo = "Audio Out Stereo"; |
| 113 | 112 |
| 114 if (kcontrol->private_value == val) | 113 if (kcontrol->private_value == val) |
| 115 return 0; | 114 return 0; |
| 116 kcontrol->private_value = val; | 115 kcontrol->private_value = val; |
| 117 » snd_soc_dapm_disable_pin(codec, val ? differential : stereo); | 116 » snd_soc_dapm_disable_pin(dapm, val ? differential : stereo); |
| 118 » snd_soc_dapm_sync(codec); | 117 » snd_soc_dapm_sync(dapm); |
| 119 » snd_soc_dapm_enable_pin(codec, val ? stereo : differential); | 118 » snd_soc_dapm_enable_pin(dapm, val ? stereo : differential); |
| 120 » snd_soc_dapm_sync(codec); | 119 » snd_soc_dapm_sync(dapm); |
| 121 | 120 |
| 122 return 1; | 121 return 1; |
| 123 } | 122 } |
| 124 | 123 |
| 125 static const struct snd_kcontrol_new audio_out_mux = { | 124 static const struct snd_kcontrol_new audio_out_mux = { |
| 126 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 127 .name = "Master Output Mux", | 126 .name = "Master Output Mux", |
| 128 .index = 0, | 127 .index = 0, |
| 129 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 128 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
| 130 .info = output_type_info, | 129 .info = output_type_info, |
| 131 .get = output_type_get, | 130 .get = output_type_get, |
| 132 .put = output_type_put, | 131 .put = output_type_put, |
| 133 .private_value = 1 /* default to stereo */ | 132 .private_value = 1 /* default to stereo */ |
| 134 }; | 133 }; |
| 135 | 134 |
| 136 /* Logic for a aic3x as connected on the s6105 ip camera ref design */ | 135 /* Logic for a aic3x as connected on the s6105 ip camera ref design */ |
| 137 static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) | 136 static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) |
| 138 { | 137 { |
| 139 struct snd_soc_codec *codec = rtd->codec; | 138 struct snd_soc_codec *codec = rtd->codec; |
| 139 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 140 | 140 |
| 141 /* Add s6105 specific widgets */ | 141 /* Add s6105 specific widgets */ |
| 142 » snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, | 142 » snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, |
| 143 ARRAY_SIZE(aic3x_dapm_widgets)); | 143 ARRAY_SIZE(aic3x_dapm_widgets)); |
| 144 | 144 |
| 145 /* Set up s6105 specific audio path audio_map */ | 145 /* Set up s6105 specific audio path audio_map */ |
| 146 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | 146 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 147 | 147 |
| 148 /* not present */ | 148 /* not present */ |
| 149 » snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); | 149 » snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); |
| 150 » snd_soc_dapm_nc_pin(codec, "LINE2L"); | 150 » snd_soc_dapm_nc_pin(dapm, "LINE2L"); |
| 151 » snd_soc_dapm_nc_pin(codec, "LINE2R"); | 151 » snd_soc_dapm_nc_pin(dapm, "LINE2R"); |
| 152 | 152 |
| 153 /* not connected */ | 153 /* not connected */ |
| 154 » snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ | 154 » snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */ |
| 155 » snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ | 155 » snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */ |
| 156 » snd_soc_dapm_nc_pin(codec, "LLOUT"); | 156 » snd_soc_dapm_nc_pin(dapm, "LLOUT"); |
| 157 » snd_soc_dapm_nc_pin(codec, "RLOUT"); | 157 » snd_soc_dapm_nc_pin(dapm, "RLOUT"); |
| 158 » snd_soc_dapm_nc_pin(codec, "HPRCOM"); | 158 » snd_soc_dapm_nc_pin(dapm, "HPRCOM"); |
| 159 | 159 |
| 160 /* always connected */ | 160 /* always connected */ |
| 161 » snd_soc_dapm_enable_pin(codec, "Audio In"); | 161 » snd_soc_dapm_enable_pin(dapm, "Audio In"); |
| 162 | 162 |
| 163 /* must correspond to audio_out_mux.private_value initializer */ | 163 /* must correspond to audio_out_mux.private_value initializer */ |
| 164 » snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); | 164 » snd_soc_dapm_disable_pin(dapm, "Audio Out Differential"); |
| 165 » snd_soc_dapm_sync(codec); | 165 » snd_soc_dapm_sync(dapm); |
| 166 » snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); | 166 » snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo"); |
| 167 | 167 |
| 168 » snd_soc_dapm_sync(codec); | 168 » snd_soc_dapm_sync(dapm); |
| 169 | 169 |
| 170 snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec)); | 170 snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec)); |
| 171 | 171 |
| 172 return 0; | 172 return 0; |
| 173 } | 173 } |
| 174 | 174 |
| 175 /* s6105 digital audio interface glue - connects codec <--> CPU */ | 175 /* s6105 digital audio interface glue - connects codec <--> CPU */ |
| 176 static struct snd_soc_dai_link s6105_dai = { | 176 static struct snd_soc_dai_link s6105_dai = { |
| 177 .name = "TLV320AIC31", | 177 .name = "TLV320AIC31", |
| 178 .stream_name = "AIC31", | 178 .stream_name = "AIC31", |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 { | 234 { |
| 235 platform_device_unregister(s6105_snd_device); | 235 platform_device_unregister(s6105_snd_device); |
| 236 } | 236 } |
| 237 | 237 |
| 238 module_init(s6105_init); | 238 module_init(s6105_init); |
| 239 module_exit(s6105_exit); | 239 module_exit(s6105_exit); |
| 240 | 240 |
| 241 MODULE_AUTHOR("Daniel Gloeckner"); | 241 MODULE_AUTHOR("Daniel Gloeckner"); |
| 242 MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver"); | 242 MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver"); |
| 243 MODULE_LICENSE("GPL"); | 243 MODULE_LICENSE("GPL"); |
| OLD | NEW |