aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad193x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad193x.c')
-rw-r--r--sound/soc/codecs/ad193x.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index eedb6f5e5823..120602130b5c 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,7 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type control_type; 26 struct regmap *regmap;
27 int sysclk; 27 int sysclk;
28}; 28};
29 29
@@ -103,12 +103,14 @@ static const struct snd_soc_dapm_route audio_paths[] = {
103static int ad193x_mute(struct snd_soc_dai *dai, int mute) 103static int ad193x_mute(struct snd_soc_dai *dai, int mute)
104{ 104{
105 struct snd_soc_codec *codec = dai->codec; 105 struct snd_soc_codec *codec = dai->codec;
106 int reg;
107 106
108 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 107 if (mute)
109 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg & 108 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
110 (~AD193X_DAC_MASTER_MUTE); 109 AD193X_DAC_MASTER_MUTE,
111 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 110 AD193X_DAC_MASTER_MUTE);
111 else
112 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
113 AD193X_DAC_MASTER_MUTE, 0);
112 114
113 return 0; 115 return 0;
114} 116}
@@ -262,7 +264,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params, 264 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai) 265 struct snd_soc_dai *dai)
264{ 266{
265 int word_len = 0, reg = 0, master_rate = 0; 267 int word_len = 0, master_rate = 0;
266 268
267 struct snd_soc_pcm_runtime *rtd = substream->private_data; 269 struct snd_soc_pcm_runtime *rtd = substream->private_data;
268 struct snd_soc_codec *codec = rtd->codec; 270 struct snd_soc_codec *codec = rtd->codec;
@@ -297,18 +299,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
297 break; 299 break;
298 } 300 }
299 301
300 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0); 302 snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0,
301 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate; 303 AD193X_PLL_INPUT_MASK, master_rate);
302 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
303 304
304 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 305 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
305 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) 306 AD193X_DAC_WORD_LEN_MASK,
306 | (word_len << AD193X_DAC_WORD_LEN_SHFT); 307 word_len << AD193X_DAC_WORD_LEN_SHFT);
307 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
308 308
309 reg = snd_soc_read(codec, AD193X_ADC_CTRL1); 309 snd_soc_update_bits(codec, AD193X_ADC_CTRL1,
310 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len; 310 AD193X_ADC_WORD_LEN_MASK, word_len);
311 snd_soc_write(codec, AD193X_ADC_CTRL1, reg);
312 311
313 return 0; 312 return 0;
314} 313}
@@ -349,10 +348,8 @@ static int ad193x_probe(struct snd_soc_codec *codec)
349 struct snd_soc_dapm_context *dapm = &codec->dapm; 348 struct snd_soc_dapm_context *dapm = &codec->dapm;
350 int ret; 349 int ret;
351 350
352 if (ad193x->control_type == SND_SOC_I2C) 351 codec->control_data = ad193x->regmap;
353 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); 352 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
354 else
355 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
356 if (ret < 0) { 353 if (ret < 0) {
357 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 354 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
358 return ret; 355 return ret;
@@ -388,6 +385,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
388}; 385};
389 386
390#if defined(CONFIG_SPI_MASTER) 387#if defined(CONFIG_SPI_MASTER)
388
389static const struct regmap_config ad193x_spi_regmap_config = {
390 .val_bits = 8,
391 .reg_bits = 16,
392 .read_flag_mask = 0x09,
393 .write_flag_mask = 0x08,
394};
395
391static int __devinit ad193x_spi_probe(struct spi_device *spi) 396static int __devinit ad193x_spi_probe(struct spi_device *spi)
392{ 397{
393 struct ad193x_priv *ad193x; 398 struct ad193x_priv *ad193x;
@@ -397,20 +402,36 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
397 if (ad193x == NULL) 402 if (ad193x == NULL)
398 return -ENOMEM; 403 return -ENOMEM;
399 404
405 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
406 if (IS_ERR(ad193x->regmap)) {
407 ret = PTR_ERR(ad193x->regmap);
408 goto err_free;
409 }
410
400 spi_set_drvdata(spi, ad193x); 411 spi_set_drvdata(spi, ad193x);
401 ad193x->control_type = SND_SOC_SPI;
402 412
403 ret = snd_soc_register_codec(&spi->dev, 413 ret = snd_soc_register_codec(&spi->dev,
404 &soc_codec_dev_ad193x, &ad193x_dai, 1); 414 &soc_codec_dev_ad193x, &ad193x_dai, 1);
405 if (ret < 0) 415 if (ret < 0)
406 kfree(ad193x); 416 goto err_regmap_exit;
417
418 return 0;
419
420err_regmap_exit:
421 regmap_exit(ad193x->regmap);
422err_free:
423 kfree(ad193x);
424
407 return ret; 425 return ret;
408} 426}
409 427
410static int __devexit ad193x_spi_remove(struct spi_device *spi) 428static int __devexit ad193x_spi_remove(struct spi_device *spi)
411{ 429{
430 struct ad193x_priv *ad193x = spi_get_drvdata(spi);
431
412 snd_soc_unregister_codec(&spi->dev); 432 snd_soc_unregister_codec(&spi->dev);
413 kfree(spi_get_drvdata(spi)); 433 regmap_exit(ad193x->regmap);
434 kfree(ad193x);
414 return 0; 435 return 0;
415} 436}
416 437
@@ -425,6 +446,12 @@ static struct spi_driver ad193x_spi_driver = {
425#endif 446#endif
426 447
427#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 448#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
449
450static const struct regmap_config ad193x_i2c_regmap_config = {
451 .val_bits = 8,
452 .reg_bits = 8,
453};
454
428static const struct i2c_device_id ad193x_id[] = { 455static const struct i2c_device_id ad193x_id[] = {
429 { "ad1936", 0 }, 456 { "ad1936", 0 },
430 { "ad1937", 0 }, 457 { "ad1937", 0 },
@@ -442,20 +469,35 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
442 if (ad193x == NULL) 469 if (ad193x == NULL)
443 return -ENOMEM; 470 return -ENOMEM;
444 471
472 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
473 if (IS_ERR(ad193x->regmap)) {
474 ret = PTR_ERR(ad193x->regmap);
475 goto err_free;
476 }
477
445 i2c_set_clientdata(client, ad193x); 478 i2c_set_clientdata(client, ad193x);
446 ad193x->control_type = SND_SOC_I2C;
447 479
448 ret = snd_soc_register_codec(&client->dev, 480 ret = snd_soc_register_codec(&client->dev,
449 &soc_codec_dev_ad193x, &ad193x_dai, 1); 481 &soc_codec_dev_ad193x, &ad193x_dai, 1);
450 if (ret < 0) 482 if (ret < 0)
451 kfree(ad193x); 483 goto err_regmap_exit;
484
485 return 0;
486
487err_regmap_exit:
488 regmap_exit(ad193x->regmap);
489err_free:
490 kfree(ad193x);
452 return ret; 491 return ret;
453} 492}
454 493
455static int __devexit ad193x_i2c_remove(struct i2c_client *client) 494static int __devexit ad193x_i2c_remove(struct i2c_client *client)
456{ 495{
496 struct ad193x_priv *ad193x = i2c_get_clientdata(client);
497
457 snd_soc_unregister_codec(&client->dev); 498 snd_soc_unregister_codec(&client->dev);
458 kfree(i2c_get_clientdata(client)); 499 regmap_exit(ad193x->regmap);
500 kfree(ad193x);
459 return 0; 501 return 0;
460} 502}
461 503