aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad1836.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad1836.c')
-rw-r--r--sound/soc/codecs/ad1836.c109
1 files changed, 42 insertions, 67 deletions
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..11b62dee842c 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/slab.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/device.h> 23#include <linux/device.h>
@@ -171,57 +172,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 172 return 0;
172} 173}
173 174
174 175#ifdef CONFIG_PM
175/* 176static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 177 pm_message_t state)
177 */
178#define AD1836_SPI_REG_SHFT 12
179#define AD1836_SPI_READ (1 << 11)
180#define AD1836_SPI_VAL_MSK 0x3FF
181
182/*
183 * write to the ad1836 register space
184 */
185
186static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
187 unsigned int value)
188{ 178{
189 u16 *reg_cache = codec->reg_cache; 179 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 180 struct snd_soc_codec *codec = socdev->card->codec;
191 181
192 if (value != reg_cache[reg]) { 182 /* reset clock control mode */
193 unsigned short buf; 183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 184 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
195 .tx_buf = &buf,
196 .len = 2,
197 };
198 struct spi_message m;
199
200 buf = (reg << AD1836_SPI_REG_SHFT) |
201 (value & AD1836_SPI_VAL_MSK);
202 spi_message_init(&m);
203 spi_message_add_tail(&t, &m);
204 ret = spi_sync(codec->control_data, &m);
205 if (ret == 0)
206 reg_cache[reg] = value;
207 }
208 185
209 return ret; 186 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 187}
211 188
212/* 189static int ad1836_soc_resume(struct platform_device *pdev)
213 * read from the ad1836 register space cache
214 */
215static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
216 unsigned int reg)
217{ 190{
218 u16 *reg_cache = codec->reg_cache; 191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec = socdev->card->codec;
219 193
220 if (reg >= codec->reg_cache_size) 194 /* restore clock control mode */
221 return -EINVAL; 195 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
196 adc_ctrl2 |= AD1836_ADC_AUX;
222 197
223 return reg_cache[reg]; 198 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 199}
200#else
201#define ad1836_soc_suspend NULL
202#define ad1836_soc_resume NULL
203#endif
225 204
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 205static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 206{
@@ -306,32 +285,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 285 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 286 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 287 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 288 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 289 INIT_LIST_HEAD(&codec->dapm_paths);
313 290
314 ad1836_dai.dev = codec->dev; 291 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 292 ad1836_codec = codec;
316 293
294 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
295 if (ret < 0) {
296 dev_err(codec->dev, "failed to set cache I/O: %d\n",
297 ret);
298 kfree(ad1836);
299 return ret;
300 }
301
317 /* default setting for ad1836 */ 302 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 303 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 304 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 305 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 306 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 307 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 308 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 309 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 310 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 311 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 312 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 313 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 319 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 320
336 ret = snd_soc_register_codec(codec); 321 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 322 if (ret != 0) {
@@ -385,19 +370,7 @@ static int ad1836_probe(struct platform_device *pdev)
385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 370 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
386 ARRAY_SIZE(ad1836_dapm_widgets)); 371 ARRAY_SIZE(ad1836_dapm_widgets));
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 372 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec);
389 373
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret;
397
398card_err:
399 snd_soc_free_pcms(socdev);
400 snd_soc_dapm_free(socdev);
401pcm_err: 374pcm_err:
402 return ret; 375 return ret;
403} 376}
@@ -416,6 +389,8 @@ static int ad1836_remove(struct platform_device *pdev)
416struct snd_soc_codec_device soc_codec_dev_ad1836 = { 389struct snd_soc_codec_device soc_codec_dev_ad1836 = {
417 .probe = ad1836_probe, 390 .probe = ad1836_probe,
418 .remove = ad1836_remove, 391 .remove = ad1836_remove,
392 .suspend = ad1836_soc_suspend,
393 .resume = ad1836_soc_resume,
419}; 394};
420EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 395EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
421 396