19
19
#include <linux/slab.h>
20
20
#include <linux/module.h>
21
21
#include <linux/device.h>
22
+ #include <linux/regmap.h>
22
23
#include <sound/core.h>
23
24
#include <sound/pcm.h>
24
25
#include <sound/ac97_codec.h>
@@ -39,33 +40,15 @@ struct wm9713_priv {
39
40
struct mutex lock ;
40
41
};
41
42
42
- static unsigned int ac97_read (struct snd_soc_codec * codec ,
43
- unsigned int reg );
44
- static int ac97_write (struct snd_soc_codec * codec ,
45
- unsigned int reg , unsigned int val );
46
-
47
- /*
48
- * WM9713 register cache
49
- * Reg 0x3c bit 15 is used by touch driver.
50
- */
51
- static const u16 wm9713_reg [] = {
52
- 0x6174 , 0x8080 , 0x8080 , 0x8080 ,
53
- 0xc880 , 0xe808 , 0xe808 , 0x0808 ,
54
- 0x00da , 0x8000 , 0xd600 , 0xaaa0 ,
55
- 0xaaa0 , 0xaaa0 , 0x0000 , 0x0000 ,
56
- 0x0f0f , 0x0040 , 0x0000 , 0x7f00 ,
57
- 0x0405 , 0x0410 , 0xbb80 , 0xbb80 ,
58
- 0x0000 , 0xbb80 , 0x0000 , 0x4523 ,
59
- 0x0000 , 0x2000 , 0x7eff , 0xffff ,
60
- 0x0000 , 0x0000 , 0x0080 , 0x0000 ,
61
- 0x0000 , 0x0000 , 0xfffe , 0xffff ,
62
- 0x0000 , 0x0000 , 0x0000 , 0xfffe ,
63
- 0x4000 , 0x0000 , 0x0000 , 0x0000 ,
64
- 0xb032 , 0x3e00 , 0x0000 , 0x0000 ,
65
- 0x0000 , 0x0000 , 0x0000 , 0x0000 ,
66
- 0x0000 , 0x0000 , 0x0000 , 0x0006 ,
67
- 0x0001 , 0x0000 , 0x574d , 0x4c13 ,
68
- };
43
+ static unsigned int ac97_read (struct snd_soc_codec * codec , unsigned int reg )
44
+ {
45
+ return snd_soc_read (codec , reg );
46
+ }
47
+ static int ac97_write (struct snd_soc_codec * codec , unsigned int reg ,
48
+ unsigned int val )
49
+ {
50
+ return snd_soc_write (codec , reg , val );
51
+ }
69
52
70
53
#define HPL_MIXER 0
71
54
#define HPR_MIXER 1
@@ -674,39 +657,97 @@ static const struct snd_soc_dapm_route wm9713_audio_map[] = {
674
657
{"Capture Mono Mux" , "Right" , "Right Capture Source" },
675
658
};
676
659
677
- static unsigned int ac97_read (struct snd_soc_codec * codec ,
678
- unsigned int reg )
660
+ static bool wm9713_readable_reg (struct device * dev , unsigned int reg )
679
661
{
680
- struct wm9713_priv * wm9713 = snd_soc_codec_get_drvdata (codec );
681
- u16 * cache = codec -> reg_cache ;
682
-
683
- if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
684
- reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
685
- reg == AC97_CD )
686
- return soc_ac97_ops -> read (wm9713 -> ac97 , reg );
687
- else {
688
- reg = reg >> 1 ;
689
-
690
- if (reg >= (ARRAY_SIZE (wm9713_reg )))
691
- return - EIO ;
692
-
693
- return cache [reg ];
662
+ switch (reg ) {
663
+ case AC97_RESET ... AC97_PCM_SURR_DAC_RATE :
664
+ case AC97_PCM_LR_ADC_RATE :
665
+ case AC97_CENTER_LFE_MASTER :
666
+ case AC97_SPDIF ... AC97_LINE1_LEVEL :
667
+ case AC97_GPIO_CFG ... 0x5c :
668
+ case AC97_CODEC_CLASS_REV ... AC97_PCI_SID :
669
+ case 0x74 ... AC97_VENDOR_ID2 :
670
+ return true;
671
+ default :
672
+ return false;
694
673
}
695
674
}
696
675
697
- static int ac97_write (struct snd_soc_codec * codec , unsigned int reg ,
698
- unsigned int val )
676
+ static bool wm9713_writeable_reg (struct device * dev , unsigned int reg )
699
677
{
700
- struct wm9713_priv * wm9713 = snd_soc_codec_get_drvdata (codec );
678
+ switch (reg ) {
679
+ case AC97_VENDOR_ID1 :
680
+ case AC97_VENDOR_ID2 :
681
+ return false;
682
+ default :
683
+ return wm9713_readable_reg (dev , reg );
684
+ }
685
+ }
701
686
702
- u16 * cache = codec -> reg_cache ;
703
- soc_ac97_ops -> write (wm9713 -> ac97 , reg , val );
704
- reg = reg >> 1 ;
705
- if (reg < (ARRAY_SIZE (wm9713_reg )))
706
- cache [reg ] = val ;
687
+ static const struct reg_default wm9713_reg_defaults [] = {
688
+ { 0x02 , 0x8080 }, /* Speaker Output Volume */
689
+ { 0x04 , 0x8080 }, /* Headphone Output Volume */
690
+ { 0x06 , 0x8080 }, /* Out3/OUT4 Volume */
691
+ { 0x08 , 0xc880 }, /* Mono Volume */
692
+ { 0x0a , 0xe808 }, /* LINEIN Volume */
693
+ { 0x0c , 0xe808 }, /* DAC PGA Volume */
694
+ { 0x0e , 0x0808 }, /* MIC PGA Volume */
695
+ { 0x10 , 0x00da }, /* MIC Routing Control */
696
+ { 0x12 , 0x8000 }, /* Record PGA Volume */
697
+ { 0x14 , 0xd600 }, /* Record Routing */
698
+ { 0x16 , 0xaaa0 }, /* PCBEEP Volume */
699
+ { 0x18 , 0xaaa0 }, /* VxDAC Volume */
700
+ { 0x1a , 0xaaa0 }, /* AUXDAC Volume */
701
+ { 0x1c , 0x0000 }, /* Output PGA Mux */
702
+ { 0x1e , 0x0000 }, /* DAC 3D control */
703
+ { 0x20 , 0x0f0f }, /* DAC Tone Control*/
704
+ { 0x22 , 0x0040 }, /* MIC Input Select & Bias */
705
+ { 0x24 , 0x0000 }, /* Output Volume Mapping & Jack */
706
+ { 0x26 , 0x7f00 }, /* Powerdown Ctrl/Stat*/
707
+ { 0x28 , 0x0405 }, /* Extended Audio ID */
708
+ { 0x2a , 0x0410 }, /* Extended Audio Start/Ctrl */
709
+ { 0x2c , 0xbb80 }, /* Audio DACs Sample Rate */
710
+ { 0x2e , 0xbb80 }, /* AUXDAC Sample Rate */
711
+ { 0x32 , 0xbb80 }, /* Audio ADCs Sample Rate */
712
+ { 0x36 , 0x4523 }, /* PCM codec control */
713
+ { 0x3a , 0x2000 }, /* SPDIF control */
714
+ { 0x3c , 0xfdff }, /* Powerdown 1 */
715
+ { 0x3e , 0xffff }, /* Powerdown 2 */
716
+ { 0x40 , 0x0000 }, /* General Purpose */
717
+ { 0x42 , 0x0000 }, /* Fast Power-Up Control */
718
+ { 0x44 , 0x0080 }, /* MCLK/PLL Control */
719
+ { 0x46 , 0x0000 }, /* MCLK/PLL Control */
720
+ { 0x4c , 0xfffe }, /* GPIO Pin Configuration */
721
+ { 0x4e , 0xffff }, /* GPIO Pin Polarity / Type */
722
+ { 0x50 , 0x0000 }, /* GPIO Pin Sticky */
723
+ { 0x52 , 0x0000 }, /* GPIO Pin Wake-Up */
724
+ /* GPIO Pin Status */
725
+ { 0x56 , 0xfffe }, /* GPIO Pin Sharing */
726
+ { 0x58 , 0x4000 }, /* GPIO PullUp/PullDown */
727
+ { 0x5a , 0x0000 }, /* Additional Functions 1 */
728
+ { 0x5c , 0x0000 }, /* Additional Functions 2 */
729
+ { 0x60 , 0xb032 }, /* ALC Control */
730
+ { 0x62 , 0x3e00 }, /* ALC / Noise Gate Control */
731
+ { 0x64 , 0x0000 }, /* AUXDAC input control */
732
+ { 0x74 , 0x0000 }, /* Digitiser Reg 1 */
733
+ { 0x76 , 0x0006 }, /* Digitiser Reg 2 */
734
+ { 0x78 , 0x0001 }, /* Digitiser Reg 3 */
735
+ { 0x7a , 0x0000 }, /* Digitiser Read Back */
736
+ };
707
737
708
- return 0 ;
709
- }
738
+ static const struct regmap_config wm9713_regmap_config = {
739
+ .reg_bits = 16 ,
740
+ .reg_stride = 2 ,
741
+ .val_bits = 16 ,
742
+ .max_register = 0x7e ,
743
+ .cache_type = REGCACHE_RBTREE ,
744
+
745
+ .reg_defaults = wm9713_reg_defaults ,
746
+ .num_reg_defaults = ARRAY_SIZE (wm9713_reg_defaults ),
747
+ .volatile_reg = regmap_ac97_default_volatile ,
748
+ .readable_reg = wm9713_readable_reg ,
749
+ .writeable_reg = wm9713_writeable_reg ,
750
+ };
710
751
711
752
/* PLL divisors */
712
753
struct _pll_div {
@@ -1173,8 +1214,7 @@ static int wm9713_soc_suspend(struct snd_soc_codec *codec)
1173
1214
static int wm9713_soc_resume (struct snd_soc_codec * codec )
1174
1215
{
1175
1216
struct wm9713_priv * wm9713 = snd_soc_codec_get_drvdata (codec );
1176
- int i , ret ;
1177
- u16 * cache = codec -> reg_cache ;
1217
+ int ret ;
1178
1218
1179
1219
ret = snd_ac97_reset (wm9713 -> ac97 , true, WM9713_VENDOR_ID ,
1180
1220
WM9713_VENDOR_ID_MASK );
@@ -1189,12 +1229,8 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1189
1229
1190
1230
/* only synchronise the codec if warm reset failed */
1191
1231
if (ret == 0 ) {
1192
- for (i = 2 ; i < ARRAY_SIZE (wm9713_reg ) << 1 ; i += 2 ) {
1193
- if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1194
- i == AC97_EXTENDED_MSTATUS || i > 0x66 )
1195
- continue ;
1196
- soc_ac97_ops -> write (wm9713 -> ac97 , i , cache [i >>1 ]);
1197
- }
1232
+ regcache_mark_dirty (codec -> component .regmap );
1233
+ snd_soc_cache_sync (codec );
1198
1234
}
1199
1235
1200
1236
return ret ;
@@ -1203,13 +1239,22 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1203
1239
static int wm9713_soc_probe (struct snd_soc_codec * codec )
1204
1240
{
1205
1241
struct wm9713_priv * wm9713 = snd_soc_codec_get_drvdata (codec );
1242
+ struct regmap * regmap ;
1206
1243
int reg ;
1207
1244
1208
1245
wm9713 -> ac97 = snd_soc_new_ac97_codec (codec , WM9713_VENDOR_ID ,
1209
1246
WM9713_VENDOR_ID_MASK );
1210
1247
if (IS_ERR (wm9713 -> ac97 ))
1211
1248
return PTR_ERR (wm9713 -> ac97 );
1212
1249
1250
+ regmap = devm_regmap_init_ac97 (wm9713 -> ac97 , & wm9713_regmap_config );
1251
+ if (IS_ERR (regmap )) {
1252
+ snd_soc_free_ac97_codec (wm9713 -> ac97 );
1253
+ return PTR_ERR (regmap );
1254
+ }
1255
+
1256
+ snd_soc_codec_init_regmap (codec , regmap );
1257
+
1213
1258
/* unmute the adc - move to kcontrol */
1214
1259
reg = ac97_read (codec , AC97_CD ) & 0x7fff ;
1215
1260
ac97_write (codec , AC97_CD , reg );
@@ -1221,6 +1266,7 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
1221
1266
{
1222
1267
struct wm9713_priv * wm9713 = snd_soc_codec_get_drvdata (codec );
1223
1268
1269
+ snd_soc_codec_exit_regmap (codec );
1224
1270
snd_soc_free_ac97_codec (wm9713 -> ac97 );
1225
1271
return 0 ;
1226
1272
}
@@ -1230,13 +1276,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1230
1276
.remove = wm9713_soc_remove ,
1231
1277
.suspend = wm9713_soc_suspend ,
1232
1278
.resume = wm9713_soc_resume ,
1233
- .read = ac97_read ,
1234
- .write = ac97_write ,
1235
1279
.set_bias_level = wm9713_set_bias_level ,
1236
- .reg_cache_size = ARRAY_SIZE (wm9713_reg ),
1237
- .reg_word_size = sizeof (u16 ),
1238
- .reg_cache_step = 2 ,
1239
- .reg_cache_default = wm9713_reg ,
1240
1280
1241
1281
.controls = wm9713_snd_ac97_controls ,
1242
1282
.num_controls = ARRAY_SIZE (wm9713_snd_ac97_controls ),
0 commit comments