aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad1836.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-09-13 06:04:51 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-13 06:08:21 -0400
commit7f22fd9c03c0b67ee6aa138bd10ae91bb0d22151 (patch)
treedc1b9e590326b5f01c280e3be18f45f47881abb3 /sound/soc/codecs/ad1836.c
parent040242ccfcd4ae878267b521d16539e7b3000527 (diff)
ASoC: ad1836: Convert to direct regmap usage.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/ad1836.c')
-rw-r--r--sound/soc/codecs/ad1836.c76
1 files changed, 53 insertions, 23 deletions
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index ae1eb51bc9da..dce6ebeef452 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -19,6 +19,8 @@
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/tlv.h> 20#include <sound/tlv.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/regmap.h>
23
22#include "ad1836.h" 24#include "ad1836.h"
23 25
24enum ad1836_type { 26enum ad1836_type {
@@ -30,6 +32,7 @@ enum ad1836_type {
30/* codec private data */ 32/* codec private data */
31struct ad1836_priv { 33struct ad1836_priv {
32 enum ad1836_type type; 34 enum ad1836_type type;
35 struct regmap *regmap;
33}; 36};
34 37
35/* 38/*
@@ -161,8 +164,8 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params, 164 struct snd_pcm_hw_params *params,
162 struct snd_soc_dai *dai) 165 struct snd_soc_dai *dai)
163{ 166{
167 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec);
164 int word_len = 0; 168 int word_len = 0;
165 struct snd_soc_codec *codec = dai->codec;
166 169
167 /* bit size */ 170 /* bit size */
168 switch (params_format(params)) { 171 switch (params_format(params)) {
@@ -178,10 +181,12 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
178 break; 181 break;
179 } 182 }
180 183
181 snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK, 184 regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1,
185 AD1836_DAC_WORD_LEN_MASK,
182 word_len << AD1836_DAC_WORD_LEN_OFFSET); 186 word_len << AD1836_DAC_WORD_LEN_OFFSET);
183 187
184 snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK, 188 regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
189 AD1836_ADC_WORD_LEN_MASK,
185 word_len << AD1836_ADC_WORD_OFFSET); 190 word_len << AD1836_ADC_WORD_OFFSET);
186 191
187 return 0; 192 return 0;
@@ -223,15 +228,17 @@ static struct snd_soc_dai_driver ad183x_dais[] = {
223#ifdef CONFIG_PM 228#ifdef CONFIG_PM
224static int ad1836_suspend(struct snd_soc_codec *codec) 229static int ad1836_suspend(struct snd_soc_codec *codec)
225{ 230{
231 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
226 /* reset clock control mode */ 232 /* reset clock control mode */
227 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, 233 return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
228 AD1836_ADC_SERFMT_MASK, 0); 234 AD1836_ADC_SERFMT_MASK, 0);
229} 235}
230 236
231static int ad1836_resume(struct snd_soc_codec *codec) 237static int ad1836_resume(struct snd_soc_codec *codec)
232{ 238{
239 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
233 /* restore clock control mode */ 240 /* restore clock control mode */
234 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, 241 return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
235 AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX); 242 AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
236} 243}
237#else 244#else
@@ -250,37 +257,30 @@ static int ad1836_probe(struct snd_soc_codec *codec)
250 num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2; 257 num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
251 num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2; 258 num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
252 259
253 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
254 if (ret < 0) {
255 dev_err(codec->dev, "failed to set cache I/O: %d\n",
256 ret);
257 return ret;
258 }
259
260 /* default setting for ad1836 */ 260 /* default setting for ad1836 */
261 /* de-emphasis: 48kHz, power-on dac */ 261 /* de-emphasis: 48kHz, power-on dac */
262 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300); 262 regmap_write(ad1836->regmap, AD1836_DAC_CTRL1, 0x300);
263 /* unmute dac channels */ 263 /* unmute dac channels */
264 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0); 264 regmap_write(ad1836->regmap, AD1836_DAC_CTRL2, 0x0);
265 /* high-pass filter enable, power-on adc */ 265 /* high-pass filter enable, power-on adc */
266 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); 266 regmap_write(ad1836->regmap, AD1836_ADC_CTRL1, 0x100);
267 /* unmute adc channles, adc aux mode */ 267 /* unmute adc channles, adc aux mode */
268 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); 268 regmap_write(ad1836->regmap, AD1836_ADC_CTRL2, 0x180);
269 /* volume */ 269 /* volume */
270 for (i = 1; i <= num_dacs; ++i) { 270 for (i = 1; i <= num_dacs; ++i) {
271 snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF); 271 regmap_write(ad1836->regmap, AD1836_DAC_L_VOL(i), 0x3FF);
272 snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF); 272 regmap_write(ad1836->regmap, AD1836_DAC_R_VOL(i), 0x3FF);
273 } 273 }
274 274
275 if (ad1836->type == AD1836) { 275 if (ad1836->type == AD1836) {
276 /* left/right diff:PGA/MUX */ 276 /* left/right diff:PGA/MUX */
277 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); 277 regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
278 ret = snd_soc_add_codec_controls(codec, ad1836_controls, 278 ret = snd_soc_add_codec_controls(codec, ad1836_controls,
279 ARRAY_SIZE(ad1836_controls)); 279 ARRAY_SIZE(ad1836_controls));
280 if (ret) 280 if (ret)
281 return ret; 281 return ret;
282 } else { 282 } else {
283 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); 283 regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
284 } 284 }
285 285
286 ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2); 286 ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
@@ -313,8 +313,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)
313/* power down chip */ 313/* power down chip */
314static int ad1836_remove(struct snd_soc_codec *codec) 314static int ad1836_remove(struct snd_soc_codec *codec)
315{ 315{
316 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
316 /* reset clock control mode */ 317 /* reset clock control mode */
317 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, 318 return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
318 AD1836_ADC_SERFMT_MASK, 0); 319 AD1836_ADC_SERFMT_MASK, 0);
319} 320}
320 321
@@ -323,8 +324,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
323 .remove = ad1836_remove, 324 .remove = ad1836_remove,
324 .suspend = ad1836_suspend, 325 .suspend = ad1836_suspend,
325 .resume = ad1836_resume, 326 .resume = ad1836_resume,
326 .reg_cache_size = AD1836_NUM_REGS,
327 .reg_word_size = sizeof(u16),
328 327
329 .controls = ad183x_controls, 328 .controls = ad183x_controls,
330 .num_controls = ARRAY_SIZE(ad183x_controls), 329 .num_controls = ARRAY_SIZE(ad183x_controls),
@@ -334,6 +333,33 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
334 .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), 333 .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
335}; 334};
336 335
336static const struct reg_default ad1836_reg_defaults[] = {
337 { AD1836_DAC_CTRL1, 0x0000 },
338 { AD1836_DAC_CTRL2, 0x0000 },
339 { AD1836_DAC_L_VOL(0), 0x0000 },
340 { AD1836_DAC_R_VOL(0), 0x0000 },
341 { AD1836_DAC_L_VOL(1), 0x0000 },
342 { AD1836_DAC_R_VOL(1), 0x0000 },
343 { AD1836_DAC_L_VOL(2), 0x0000 },
344 { AD1836_DAC_R_VOL(2), 0x0000 },
345 { AD1836_DAC_L_VOL(3), 0x0000 },
346 { AD1836_DAC_R_VOL(3), 0x0000 },
347 { AD1836_ADC_CTRL1, 0x0000 },
348 { AD1836_ADC_CTRL2, 0x0000 },
349 { AD1836_ADC_CTRL3, 0x0000 },
350};
351
352static const struct regmap_config ad1836_regmap_config = {
353 .val_bits = 12,
354 .reg_bits = 4,
355 .read_flag_mask = 0x08,
356
357 .max_register = AD1836_ADC_CTRL3,
358 .reg_defaults = ad1836_reg_defaults,
359 .num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),
360 .cache_type = REGCACHE_RBTREE,
361};
362
337static int __devinit ad1836_spi_probe(struct spi_device *spi) 363static int __devinit ad1836_spi_probe(struct spi_device *spi)
338{ 364{
339 struct ad1836_priv *ad1836; 365 struct ad1836_priv *ad1836;
@@ -344,6 +370,10 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi)
344 if (ad1836 == NULL) 370 if (ad1836 == NULL)
345 return -ENOMEM; 371 return -ENOMEM;
346 372
373 ad1836->regmap = devm_regmap_init_spi(spi, &ad1836_regmap_config);
374 if (IS_ERR(ad1836->regmap))
375 return PTR_ERR(ad1836->regmap);
376
347 ad1836->type = spi_get_device_id(spi)->driver_data; 377 ad1836->type = spi_get_device_id(spi)->driver_data;
348 378
349 spi_set_drvdata(spi, ad1836); 379 spi_set_drvdata(spi, ad1836);