aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/cs4271.c
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2013-03-07 17:53:12 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-14 21:23:26 -0400
commit1b1861ead4f9fd7314acb2a8950a2b75ad2c8af5 (patch)
tree40b7df03847d88a0d4b4f907311468d9aba0a008 /sound/soc/codecs/cs4271.c
parentf6161aa153581da4a3867a2d1a7caf4be19b6ec9 (diff)
ASoC: cs4271: convert to direct regmap API usage
By using the regmap API directly, we can make use of the .write_flag_mask for SPI, which allows us to drop the strange register hacks that were necessary so far. Signed-off-by: Daniel Mack <zonque@gmail.com> Acked-by: Alexander Sverdlin <alexander.sverdlin@gmx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/cs4271.c')
-rw-r--r--sound/soc/codecs/cs4271.c159
1 files changed, 91 insertions, 68 deletions
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 2415a4118dbd..ac0d3b4844a8 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -39,17 +39,15 @@
39 39
40/* 40/*
41 * CS4271 registers 41 * CS4271 registers
42 * High byte represents SPI chip address (0x10) + write command (0)
43 * Low byte - codec register address
44 */ 42 */
45#define CS4271_MODE1 0x2001 /* Mode Control 1 */ 43#define CS4271_MODE1 0x01 /* Mode Control 1 */
46#define CS4271_DACCTL 0x2002 /* DAC Control */ 44#define CS4271_DACCTL 0x02 /* DAC Control */
47#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */ 45#define CS4271_DACVOL 0x03 /* DAC Volume & Mixing Control */
48#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */ 46#define CS4271_VOLA 0x04 /* DAC Channel A Volume Control */
49#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */ 47#define CS4271_VOLB 0x05 /* DAC Channel B Volume Control */
50#define CS4271_ADCCTL 0x2006 /* ADC Control */ 48#define CS4271_ADCCTL 0x06 /* ADC Control */
51#define CS4271_MODE2 0x2007 /* Mode Control 2 */ 49#define CS4271_MODE2 0x07 /* Mode Control 2 */
52#define CS4271_CHIPID 0x2008 /* Chip ID */ 50#define CS4271_CHIPID 0x08 /* Chip ID */
53 51
54#define CS4271_FIRSTREG CS4271_MODE1 52#define CS4271_FIRSTREG CS4271_MODE1
55#define CS4271_LASTREG CS4271_MODE2 53#define CS4271_LASTREG CS4271_MODE2
@@ -144,23 +142,27 @@
144 * Array do not include Chip ID, as codec driver does not use 142 * Array do not include Chip ID, as codec driver does not use
145 * registers read operations at all 143 * registers read operations at all
146 */ 144 */
147static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = { 145static const struct reg_default cs4271_reg_defaults[] = {
148 0, 146 { CS4271_MODE1, 0, },
149 0, 147 { CS4271_DACCTL, CS4271_DACCTL_AMUTE, },
150 CS4271_DACCTL_AMUTE, 148 { CS4271_DACVOL, CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, },
151 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, 149 { CS4271_VOLA, 0, },
152 0, 150 { CS4271_VOLB, 0, },
153 0, 151 { CS4271_ADCCTL, 0, },
154 0, 152 { CS4271_MODE2, 0, },
155 0,
156}; 153};
157 154
155static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
156{
157 return reg == CS4271_CHIPID;
158}
159
158struct cs4271_private { 160struct cs4271_private {
159 /* SND_SOC_I2C or SND_SOC_SPI */ 161 /* SND_SOC_I2C or SND_SOC_SPI */
160 enum snd_soc_control_type bus_type;
161 unsigned int mclk; 162 unsigned int mclk;
162 bool master; 163 bool master;
163 bool deemph; 164 bool deemph;
165 struct regmap *regmap;
164 /* Current sample rate for de-emphasis control */ 166 /* Current sample rate for de-emphasis control */
165 int rate; 167 int rate;
166 /* GPIO driving Reset pin, if any */ 168 /* GPIO driving Reset pin, if any */
@@ -210,14 +212,14 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
210 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 212 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
211 case SND_SOC_DAIFMT_LEFT_J: 213 case SND_SOC_DAIFMT_LEFT_J:
212 val |= CS4271_MODE1_DAC_DIF_LJ; 214 val |= CS4271_MODE1_DAC_DIF_LJ;
213 ret = snd_soc_update_bits(codec, CS4271_ADCCTL, 215 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
214 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ); 216 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
215 if (ret < 0) 217 if (ret < 0)
216 return ret; 218 return ret;
217 break; 219 break;
218 case SND_SOC_DAIFMT_I2S: 220 case SND_SOC_DAIFMT_I2S:
219 val |= CS4271_MODE1_DAC_DIF_I2S; 221 val |= CS4271_MODE1_DAC_DIF_I2S;
220 ret = snd_soc_update_bits(codec, CS4271_ADCCTL, 222 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
221 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S); 223 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
222 if (ret < 0) 224 if (ret < 0)
223 return ret; 225 return ret;
@@ -227,7 +229,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
227 return -EINVAL; 229 return -EINVAL;
228 } 230 }
229 231
230 ret = snd_soc_update_bits(codec, CS4271_MODE1, 232 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
231 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val); 233 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
232 if (ret < 0) 234 if (ret < 0)
233 return ret; 235 return ret;
@@ -252,7 +254,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec)
252 val <<= 4; 254 val <<= 4;
253 } 255 }
254 256
255 ret = snd_soc_update_bits(codec, CS4271_DACCTL, 257 ret = regmap_update_bits(cs4271->regmap, CS4271_DACCTL,
256 CS4271_DACCTL_DEM_MASK, val); 258 CS4271_DACCTL_DEM_MASK, val);
257 if (ret < 0) 259 if (ret < 0)
258 return ret; 260 return ret;
@@ -341,14 +343,14 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
341 !dai->capture_active) || 343 !dai->capture_active) ||
342 (substream->stream == SNDRV_PCM_STREAM_CAPTURE && 344 (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
343 !dai->playback_active)) { 345 !dai->playback_active)) {
344 ret = snd_soc_update_bits(codec, CS4271_MODE2, 346 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
345 CS4271_MODE2_PDN, 347 CS4271_MODE2_PDN,
346 CS4271_MODE2_PDN); 348 CS4271_MODE2_PDN);
347 if (ret < 0) 349 if (ret < 0)
348 return ret; 350 return ret;
349 351
350 ret = snd_soc_update_bits(codec, CS4271_MODE2, 352 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
351 CS4271_MODE2_PDN, 0); 353 CS4271_MODE2_PDN, 0);
352 if (ret < 0) 354 if (ret < 0)
353 return ret; 355 return ret;
354 } 356 }
@@ -378,7 +380,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
378 380
379 val |= cs4271_clk_tab[i].ratio_mask; 381 val |= cs4271_clk_tab[i].ratio_mask;
380 382
381 ret = snd_soc_update_bits(codec, CS4271_MODE1, 383 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
382 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); 384 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
383 if (ret < 0) 385 if (ret < 0)
384 return ret; 386 return ret;
@@ -389,6 +391,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
389static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute) 391static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
390{ 392{
391 struct snd_soc_codec *codec = dai->codec; 393 struct snd_soc_codec *codec = dai->codec;
394 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
392 int ret; 395 int ret;
393 int val_a = 0; 396 int val_a = 0;
394 int val_b = 0; 397 int val_b = 0;
@@ -398,10 +401,13 @@ static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
398 val_b = CS4271_VOLB_MUTE; 401 val_b = CS4271_VOLB_MUTE;
399 } 402 }
400 403
401 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a); 404 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLA,
405 CS4271_VOLA_MUTE, val_a);
402 if (ret < 0) 406 if (ret < 0)
403 return ret; 407 return ret;
404 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b); 408
409 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLB,
410 CS4271_VOLB_MUTE, val_b);
405 if (ret < 0) 411 if (ret < 0)
406 return ret; 412 return ret;
407 413
@@ -463,25 +469,33 @@ static struct snd_soc_dai_driver cs4271_dai = {
463static int cs4271_soc_suspend(struct snd_soc_codec *codec) 469static int cs4271_soc_suspend(struct snd_soc_codec *codec)
464{ 470{
465 int ret; 471 int ret;
472 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
473
466 /* Set power-down bit */ 474 /* Set power-down bit */
467 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 475 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
468 CS4271_MODE2_PDN); 476 CS4271_MODE2_PDN, CS4271_MODE2_PDN);
469 if (ret < 0) 477 if (ret < 0)
470 return ret; 478 return ret;
479
471 return 0; 480 return 0;
472} 481}
473 482
474static int cs4271_soc_resume(struct snd_soc_codec *codec) 483static int cs4271_soc_resume(struct snd_soc_codec *codec)
475{ 484{
476 int ret; 485 int ret;
486 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
487
477 /* Restore codec state */ 488 /* Restore codec state */
478 ret = snd_soc_cache_sync(codec); 489 ret = regcache_sync(cs4271->regmap);
479 if (ret < 0) 490 if (ret < 0)
480 return ret; 491 return ret;
492
481 /* then disable the power-down bit */ 493 /* then disable the power-down bit */
482 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); 494 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
495 CS4271_MODE2_PDN, 0);
483 if (ret < 0) 496 if (ret < 0)
484 return ret; 497 return ret;
498
485 return 0; 499 return 0;
486} 500}
487#else 501#else
@@ -542,40 +556,22 @@ static int cs4271_probe(struct snd_soc_codec *codec)
542 556
543 cs4271->gpio_nreset = gpio_nreset; 557 cs4271->gpio_nreset = gpio_nreset;
544 558
545 /* 559 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
546 * In case of I2C, chip address specified in board data. 560 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
547 * So cache IO operations use 8 bit codec register address. 561 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
548 * In case of SPI, chip address and register address
549 * passed together as 16 bit value.
550 * Anyway, register address is masked with 0xFF inside
551 * soc-cache code.
552 */
553 if (cs4271->bus_type == SND_SOC_SPI)
554 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
555 cs4271->bus_type);
556 else
557 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
558 cs4271->bus_type);
559 if (ret) {
560 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
561 return ret;
562 }
563
564 ret = snd_soc_update_bits(codec, CS4271_MODE2,
565 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
566 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
567 if (ret < 0) 562 if (ret < 0)
568 return ret; 563 return ret;
569 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); 564 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
565 CS4271_MODE2_PDN, 0);
570 if (ret < 0) 566 if (ret < 0)
571 return ret; 567 return ret;
572 /* Power-up sequence requires 85 uS */ 568 /* Power-up sequence requires 85 uS */
573 udelay(85); 569 udelay(85);
574 570
575 if (amutec_eq_bmutec) 571 if (amutec_eq_bmutec)
576 snd_soc_update_bits(codec, CS4271_MODE2, 572 regmap_update_bits(cs4271->regmap, CS4271_MODE2,
577 CS4271_MODE2_MUTECAEQUB, 573 CS4271_MODE2_MUTECAEQUB,
578 CS4271_MODE2_MUTECAEQUB); 574 CS4271_MODE2_MUTECAEQUB);
579 575
580 return snd_soc_add_codec_controls(codec, cs4271_snd_controls, 576 return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
581 ARRAY_SIZE(cs4271_snd_controls)); 577 ARRAY_SIZE(cs4271_snd_controls));
@@ -597,13 +593,24 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
597 .remove = cs4271_remove, 593 .remove = cs4271_remove,
598 .suspend = cs4271_soc_suspend, 594 .suspend = cs4271_soc_suspend,
599 .resume = cs4271_soc_resume, 595 .resume = cs4271_soc_resume,
600 .reg_cache_default = cs4271_dflt_reg,
601 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
602 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
603 .compress_type = SND_SOC_FLAT_COMPRESSION,
604}; 596};
605 597
606#if defined(CONFIG_SPI_MASTER) 598#if defined(CONFIG_SPI_MASTER)
599
600static const struct regmap_config cs4271_spi_regmap = {
601 .reg_bits = 16,
602 .val_bits = 8,
603 .max_register = CS4271_LASTREG,
604 .read_flag_mask = 0x21,
605 .write_flag_mask = 0x20,
606
607 .reg_defaults = cs4271_reg_defaults,
608 .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults),
609 .cache_type = REGCACHE_RBTREE,
610
611 .volatile_reg = cs4271_volatile_reg,
612};
613
607static int cs4271_spi_probe(struct spi_device *spi) 614static int cs4271_spi_probe(struct spi_device *spi)
608{ 615{
609 struct cs4271_private *cs4271; 616 struct cs4271_private *cs4271;
@@ -613,7 +620,9 @@ static int cs4271_spi_probe(struct spi_device *spi)
613 return -ENOMEM; 620 return -ENOMEM;
614 621
615 spi_set_drvdata(spi, cs4271); 622 spi_set_drvdata(spi, cs4271);
616 cs4271->bus_type = SND_SOC_SPI; 623 cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap);
624 if (IS_ERR(cs4271->regmap))
625 return PTR_ERR(cs4271->regmap);
617 626
618 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, 627 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
619 &cs4271_dai, 1); 628 &cs4271_dai, 1);
@@ -643,6 +652,18 @@ static const struct i2c_device_id cs4271_i2c_id[] = {
643}; 652};
644MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); 653MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
645 654
655static const struct regmap_config cs4271_i2c_regmap = {
656 .reg_bits = 8,
657 .val_bits = 8,
658 .max_register = CS4271_LASTREG,
659
660 .reg_defaults = cs4271_reg_defaults,
661 .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults),
662 .cache_type = REGCACHE_RBTREE,
663
664 .volatile_reg = cs4271_volatile_reg,
665};
666
646static int cs4271_i2c_probe(struct i2c_client *client, 667static int cs4271_i2c_probe(struct i2c_client *client,
647 const struct i2c_device_id *id) 668 const struct i2c_device_id *id)
648{ 669{
@@ -653,7 +674,9 @@ static int cs4271_i2c_probe(struct i2c_client *client,
653 return -ENOMEM; 674 return -ENOMEM;
654 675
655 i2c_set_clientdata(client, cs4271); 676 i2c_set_clientdata(client, cs4271);
656 cs4271->bus_type = SND_SOC_I2C; 677 cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap);
678 if (IS_ERR(cs4271->regmap))
679 return PTR_ERR(cs4271->regmap);
657 680
658 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, 681 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
659 &cs4271_dai, 1); 682 &cs4271_dai, 1);