1818#include <linux/slab.h>
1919#include <linux/module.h>
2020#include <linux/device.h>
21+ #include <linux/regmap.h>
2122#include <sound/core.h>
2223#include <sound/pcm.h>
2324#include <sound/ac97_codec.h>
2627#include <sound/soc.h>
2728#include <sound/tlv.h>
2829
29- #include "stac9766.h"
30-
3130#define STAC9766_VENDOR_ID 0x83847666
3231#define STAC9766_VENDOR_ID_MASK 0xffffffff
3332
34- /*
35- * STAC9766 register cache
36- */
37- static const u16 stac9766_reg [] = {
38- 0x6A90 , 0x8000 , 0x8000 , 0x8000 , /* 6 */
39- 0x0000 , 0x0000 , 0x8008 , 0x8008 , /* e */
40- 0x8808 , 0x8808 , 0x8808 , 0x8808 , /* 16 */
41- 0x8808 , 0x0000 , 0x8000 , 0x0000 , /* 1e */
42- 0x0000 , 0x0000 , 0x0000 , 0x000f , /* 26 */
43- 0x0a05 , 0x0400 , 0xbb80 , 0x0000 , /* 2e */
44- 0x0000 , 0xbb80 , 0x0000 , 0x0000 , /* 36 */
45- 0x0000 , 0x2000 , 0x0000 , 0x0100 , /* 3e */
46- 0x0000 , 0x0000 , 0x0080 , 0x0000 , /* 46 */
47- 0x0000 , 0x0000 , 0x0003 , 0xffff , /* 4e */
48- 0x0000 , 0x0000 , 0x0000 , 0x0000 , /* 56 */
49- 0x4000 , 0x0000 , 0x0000 , 0x0000 , /* 5e */
50- 0x1201 , 0xFFFF , 0xFFFF , 0x0000 , /* 66 */
51- 0x0000 , 0x0000 , 0x0000 , 0x0000 , /* 6e */
52- 0x0000 , 0x0000 , 0x0000 , 0x0006 , /* 76 */
53- 0x0000 , 0x0000 , 0x0000 , 0x0000 , /* 7e */
33+ #define AC97_STAC_DA_CONTROL 0x6A
34+ #define AC97_STAC_ANALOG_SPECIAL 0x6E
35+ #define AC97_STAC_STEREO_MIC 0x78
36+
37+ static const struct reg_default stac9766_reg_defaults [] = {
38+ { 0x02 , 0x8000 },
39+ { 0x04 , 0x8000 },
40+ { 0x06 , 0x8000 },
41+ { 0x0a , 0x0000 },
42+ { 0x0c , 0x8008 },
43+ { 0x0e , 0x8008 },
44+ { 0x10 , 0x8808 },
45+ { 0x12 , 0x8808 },
46+ { 0x14 , 0x8808 },
47+ { 0x16 , 0x8808 },
48+ { 0x18 , 0x8808 },
49+ { 0x1a , 0x0000 },
50+ { 0x1c , 0x8000 },
51+ { 0x20 , 0x0000 },
52+ { 0x22 , 0x0000 },
53+ { 0x28 , 0x0a05 },
54+ { 0x2c , 0xbb80 },
55+ { 0x32 , 0xbb80 },
56+ { 0x3a , 0x2000 },
57+ { 0x3e , 0x0100 },
58+ { 0x4c , 0x0300 },
59+ { 0x4e , 0xffff },
60+ { 0x50 , 0x0000 },
61+ { 0x52 , 0x0000 },
62+ { 0x54 , 0x0000 },
63+ { 0x6a , 0x0000 },
64+ { 0x6e , 0x1000 },
65+ { 0x72 , 0x0000 },
66+ { 0x78 , 0x0000 },
67+ };
68+
69+ static const struct regmap_config stac9766_regmap_config = {
70+ .reg_bits = 16 ,
71+ .reg_stride = 2 ,
72+ .val_bits = 16 ,
73+ .max_register = 0x78 ,
74+ .cache_type = REGCACHE_RBTREE ,
75+
76+ .volatile_reg = regmap_ac97_default_volatile ,
77+
78+ .reg_defaults = stac9766_reg_defaults ,
79+ .num_reg_defaults = ARRAY_SIZE (stac9766_reg_defaults ),
5480};
5581
5682static const char * stac9766_record_mux [] = {"Mic" , "CD" , "Video" , "AUX" ,
@@ -139,90 +165,39 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
139165 SOC_ENUM ("Pop Bypass Mux" , stac9766_popbypass_enum ),
140166};
141167
142- static int stac9766_ac97_write (struct snd_soc_codec * codec , unsigned int reg ,
143- unsigned int val )
144- {
145- struct snd_ac97 * ac97 = snd_soc_codec_get_drvdata (codec );
146- u16 * cache = codec -> reg_cache ;
147-
148- if (reg > AC97_STAC_PAGE0 ) {
149- stac9766_ac97_write (codec , AC97_INT_PAGING , 0 );
150- soc_ac97_ops -> write (ac97 , reg , val );
151- stac9766_ac97_write (codec , AC97_INT_PAGING , 1 );
152- return 0 ;
153- }
154- if (reg / 2 >= ARRAY_SIZE (stac9766_reg ))
155- return - EIO ;
156-
157- soc_ac97_ops -> write (ac97 , reg , val );
158- cache [reg / 2 ] = val ;
159- return 0 ;
160- }
161-
162- static unsigned int stac9766_ac97_read (struct snd_soc_codec * codec ,
163- unsigned int reg )
164- {
165- struct snd_ac97 * ac97 = snd_soc_codec_get_drvdata (codec );
166- u16 val = 0 , * cache = codec -> reg_cache ;
167-
168- if (reg > AC97_STAC_PAGE0 ) {
169- stac9766_ac97_write (codec , AC97_INT_PAGING , 0 );
170- val = soc_ac97_ops -> read (ac97 , reg - AC97_STAC_PAGE0 );
171- stac9766_ac97_write (codec , AC97_INT_PAGING , 1 );
172- return val ;
173- }
174- if (reg / 2 >= ARRAY_SIZE (stac9766_reg ))
175- return - EIO ;
176-
177- if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
178- reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
179- reg == AC97_VENDOR_ID2 ) {
180-
181- val = soc_ac97_ops -> read (ac97 , reg );
182- return val ;
183- }
184- return cache [reg / 2 ];
185- }
186-
187168static int ac97_analog_prepare (struct snd_pcm_substream * substream ,
188169 struct snd_soc_dai * dai )
189170{
190171 struct snd_soc_codec * codec = dai -> codec ;
191172 struct snd_pcm_runtime * runtime = substream -> runtime ;
192- unsigned short reg , vra ;
193-
194- vra = stac9766_ac97_read (codec , AC97_EXTENDED_STATUS );
173+ unsigned short reg ;
195174
196- vra |= 0x1 ; /* enable variable rate audio */
197- vra &= ~0x4 ; /* disable SPDIF output */
198-
199- stac9766_ac97_write (codec , AC97_EXTENDED_STATUS , vra );
175+ /* enable variable rate audio, disable SPDIF output */
176+ snd_soc_update_bits (codec , AC97_EXTENDED_STATUS , 0x5 , 0x1 );
200177
201178 if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
202179 reg = AC97_PCM_FRONT_DAC_RATE ;
203180 else
204181 reg = AC97_PCM_LR_ADC_RATE ;
205182
206- return stac9766_ac97_write (codec , reg , runtime -> rate );
183+ return snd_soc_write (codec , reg , runtime -> rate );
207184}
208185
209186static int ac97_digital_prepare (struct snd_pcm_substream * substream ,
210187 struct snd_soc_dai * dai )
211188{
212189 struct snd_soc_codec * codec = dai -> codec ;
213190 struct snd_pcm_runtime * runtime = substream -> runtime ;
214- unsigned short reg , vra ;
215-
216- stac9766_ac97_write (codec , AC97_SPDIF , 0x2002 );
191+ unsigned short reg ;
217192
218- vra = stac9766_ac97_read (codec , AC97_EXTENDED_STATUS );
219- vra |= 0x5 ; /* Enable VRA and SPDIF out */
193+ snd_soc_write (codec , AC97_SPDIF , 0x2002 );
220194
221- stac9766_ac97_write (codec , AC97_EXTENDED_STATUS , vra );
195+ /* Enable VRA and SPDIF out */
196+ snd_soc_update_bits (codec , AC97_EXTENDED_STATUS , 0x5 , 0x5 );
222197
223198 reg = AC97_PCM_FRONT_DAC_RATE ;
224199
225- return stac9766_ac97_write (codec , reg , runtime -> rate );
200+ return snd_soc_write (codec , reg , runtime -> rate );
226201}
227202
228203static int stac9766_set_bias_level (struct snd_soc_codec * codec ,
@@ -232,11 +207,11 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
232207 case SND_SOC_BIAS_ON : /* full On */
233208 case SND_SOC_BIAS_PREPARE : /* partial On */
234209 case SND_SOC_BIAS_STANDBY : /* Off, with power */
235- stac9766_ac97_write (codec , AC97_POWERDOWN , 0x0000 );
210+ snd_soc_write (codec , AC97_POWERDOWN , 0x0000 );
236211 break ;
237212 case SND_SOC_BIAS_OFF : /* Off, without power */
238213 /* disable everything including AC link */
239- stac9766_ac97_write (codec , AC97_POWERDOWN , 0xffff );
214+ snd_soc_write (codec , AC97_POWERDOWN , 0xffff );
240215 break ;
241216 }
242217 return 0 ;
@@ -300,21 +275,34 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
300275static int stac9766_codec_probe (struct snd_soc_codec * codec )
301276{
302277 struct snd_ac97 * ac97 ;
278+ struct regmap * regmap ;
279+ int ret ;
303280
304281 ac97 = snd_soc_new_ac97_codec (codec , STAC9766_VENDOR_ID ,
305282 STAC9766_VENDOR_ID_MASK );
306283 if (IS_ERR (ac97 ))
307284 return PTR_ERR (ac97 );
308285
286+ regmap = regmap_init_ac97 (ac97 , & stac9766_regmap_config );
287+ if (IS_ERR (regmap )) {
288+ ret = PTR_ERR (regmap );
289+ goto err_free_ac97 ;
290+ }
291+
292+ snd_soc_codec_init_regmap (codec , regmap );
309293 snd_soc_codec_set_drvdata (codec , ac97 );
310294
311295 return 0 ;
296+ err_free_ac97 :
297+ snd_soc_free_ac97_codec (ac97 );
298+ return ret ;
312299}
313300
314301static int stac9766_codec_remove (struct snd_soc_codec * codec )
315302{
316303 struct snd_ac97 * ac97 = snd_soc_codec_get_drvdata (codec );
317304
305+ snd_soc_codec_exit_regmap (codec );
318306 snd_soc_free_ac97_codec (ac97 );
319307 return 0 ;
320308}
@@ -324,17 +312,11 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
324312 .controls = stac9766_snd_ac97_controls ,
325313 .num_controls = ARRAY_SIZE (stac9766_snd_ac97_controls ),
326314 },
327- .write = stac9766_ac97_write ,
328- .read = stac9766_ac97_read ,
329315 .set_bias_level = stac9766_set_bias_level ,
330316 .suspend_bias_off = true,
331317 .probe = stac9766_codec_probe ,
332318 .remove = stac9766_codec_remove ,
333319 .resume = stac9766_codec_resume ,
334- .reg_cache_size = ARRAY_SIZE (stac9766_reg ),
335- .reg_word_size = sizeof (u16 ),
336- .reg_cache_step = 2 ,
337- .reg_cache_default = stac9766_reg ,
338320};
339321
340322static int stac9766_probe (struct platform_device * pdev )
0 commit comments