Date: | 2012-09-15 18:34:30 (8 years 4 months ago) |
---|---|
Author: | Lars C. |
Commit: | d8b0b5ca4e22bc58adf579946c0a06adaeed122b |
Message: | ASoC: jz4740: Use regmap Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> |
Files: |
sound/soc/codecs/Kconfig (1 diff) sound/soc/codecs/jz4740.c (12 diffs) |
Change Details
sound/soc/codecs/Kconfig | ||
---|---|---|
211 | 211 | tristate |
212 | 212 | |
213 | 213 | config SND_SOC_JZ4740_CODEC |
214 | select REGMAP_MMIO | |
214 | 215 | tristate |
215 | 216 | |
216 | 217 | config SND_SOC_L3 |
sound/soc/codecs/jz4740.c | ||
---|---|---|
16 | 16 | #include <linux/platform_device.h> |
17 | 17 | #include <linux/slab.h> |
18 | 18 | #include <linux/io.h> |
19 | #include <linux/regmap.h> | |
19 | 20 | |
20 | 21 | #include <linux/delay.h> |
21 | 22 | |
... | ... | |
27 | 28 | #include <sound/tlv.h> |
28 | 29 | |
29 | 30 | #define JZ4740_REG_CODEC_1 0x0 |
30 | #define JZ4740_REG_CODEC_2 0x1 | |
31 | #define JZ4740_REG_CODEC_2 0x4 | |
31 | 32 | |
32 | 33 | #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) |
33 | 34 | #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) |
... | ... | |
68 | 69 | #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 |
69 | 70 | #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 |
70 | 71 | |
71 | static const uint32_t jz4740_codec_regs[] = { | |
72 | 0x021b2302, 0x00170803, | |
72 | static const struct reg_default jz4740_codec_reg_defaults[] = { | |
73 | { JZ4740_REG_CODEC_1, 0x021b2302 }, | |
74 | { JZ4740_REG_CODEC_2, 0x00170803 }, | |
73 | 75 | }; |
74 | 76 | |
75 | 77 | struct jz4740_codec { |
76 | void __iomem *base; | |
78 | struct regmap *regmap; | |
77 | 79 | }; |
78 | 80 | |
79 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, | |
80 | unsigned int reg) | |
81 | { | |
82 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
83 | return readl(jz4740_codec->base + (reg << 2)); | |
84 | } | |
85 | ||
86 | static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, | |
87 | unsigned int val) | |
88 | { | |
89 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
90 | u32 *cache = codec->reg_cache; | |
91 | ||
92 | cache[reg] = val; | |
93 | writel(val, jz4740_codec->base + (reg << 2)); | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
98 | 81 | static const unsigned int jz4740_mic_tlv[] = { |
99 | 82 | TLV_DB_RANGE_HEAD(2), |
100 | 83 | 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), |
... | ... | |
172 | 155 | static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, |
173 | 156 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
174 | 157 | { |
158 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec); | |
175 | 159 | uint32_t val; |
176 | struct snd_soc_codec *codec = dai->codec; | |
177 | 160 | |
178 | 161 | switch (params_rate(params)) { |
179 | 162 | case 8000: |
... | ... | |
209 | 192 | |
210 | 193 | val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; |
211 | 194 | |
212 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_2, | |
195 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_2, | |
213 | 196 | JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); |
214 | 197 | |
215 | 198 | return 0; |
... | ... | |
239 | 222 | .symmetric_rates = 1, |
240 | 223 | }; |
241 | 224 | |
242 | static void jz4740_codec_wakeup(struct snd_soc_codec *codec) | |
225 | static void jz4740_codec_wakeup(struct regmap *regmap) | |
243 | 226 | { |
244 | int i; | |
245 | uint32_t *cache = codec->reg_cache; | |
246 | ||
247 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | |
227 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, | |
248 | 228 | JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); |
249 | 229 | udelay(2); |
250 | 230 | |
251 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | |
231 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, | |
252 | 232 | JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); |
253 | 233 | |
254 | for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i) | |
255 | jz4740_codec_write(codec, i, cache[i]); | |
234 | regcache_sync(regmap); | |
256 | 235 | } |
257 | 236 | |
258 | 237 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, |
259 | 238 | enum snd_soc_bias_level level) |
260 | 239 | { |
240 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
241 | struct regmap *regmap = jz4740_codec->regmap; | |
261 | 242 | unsigned int mask; |
262 | 243 | unsigned int value; |
263 | 244 | |
... | ... | |
267 | 248 | case SND_SOC_BIAS_PREPARE: |
268 | 249 | mask = JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
269 | 250 | value = 0; |
270 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | |
251 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); | |
271 | 252 | |
272 | 253 | msleep(500); |
273 | 254 | mask = JZ4740_CODEC_1_VREF_DISABLE | |
274 | 255 | JZ4740_CODEC_1_VREF_AMP_DISABLE; |
275 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, 0); | |
256 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, 0); | |
276 | 257 | break; |
277 | 258 | case SND_SOC_BIAS_STANDBY: |
278 | 259 | /* The only way to clear the suspend flag is to reset the codec */ |
279 | 260 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) |
280 | jz4740_codec_wakeup(codec); | |
261 | jz4740_codec_wakeup(regmap); | |
281 | 262 | |
282 | 263 | mask = JZ4740_CODEC_1_VREF_DISABLE | |
283 | 264 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
... | ... | |
286 | 267 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
287 | 268 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
288 | 269 | |
289 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | |
270 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); | |
290 | 271 | break; |
291 | 272 | case SND_SOC_BIAS_OFF: |
292 | 273 | mask = JZ4740_CODEC_1_SUSPEND; |
293 | 274 | value = JZ4740_CODEC_1_SUSPEND; |
294 | 275 | |
295 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | |
276 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); | |
277 | regcache_mark_dirty(regmap); | |
296 | 278 | break; |
297 | 279 | default: |
298 | 280 | break; |
... | ... | |
305 | 287 | |
306 | 288 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) |
307 | 289 | { |
308 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | |
290 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
291 | ||
292 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, | |
309 | 293 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
310 | 294 | |
311 | 295 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
... | ... | |
342 | 326 | .remove = jz4740_codec_dev_remove, |
343 | 327 | .suspend = jz4740_codec_suspend, |
344 | 328 | .resume = jz4740_codec_resume, |
345 | .read = jz4740_codec_read, | |
346 | .write = jz4740_codec_write, | |
347 | 329 | .set_bias_level = jz4740_codec_set_bias_level, |
348 | .reg_cache_default = jz4740_codec_regs, | |
349 | .reg_word_size = sizeof(u32), | |
350 | .reg_cache_size = 2, | |
351 | 330 | |
352 | 331 | .controls = jz4740_codec_controls, |
353 | 332 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
... | ... | |
357 | 336 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), |
358 | 337 | }; |
359 | 338 | |
339 | static const struct regmap_config jz4740_codec_regmap_config = { | |
340 | .reg_bits = 32, | |
341 | .reg_stride = 4, | |
342 | .val_bits = 32, | |
343 | .max_register = JZ4740_REG_CODEC_2, | |
344 | ||
345 | .reg_defaults = jz4740_codec_reg_defaults, | |
346 | .num_reg_defaults = ARRAY_SIZE(jz4740_codec_reg_defaults), | |
347 | .cache_type = REGCACHE_RBTREE, | |
348 | }; | |
349 | ||
360 | 350 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) |
361 | 351 | { |
362 | 352 | int ret; |
363 | 353 | struct jz4740_codec *jz4740_codec; |
364 | 354 | struct resource *mem; |
355 | void __iomem *base; | |
365 | 356 | |
366 | 357 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), |
367 | 358 | GFP_KERNEL); |
... | ... | |
369 | 360 | return -ENOMEM; |
370 | 361 | |
371 | 362 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
372 | jz4740_codec->base = devm_request_and_ioremap(&pdev->dev, mem); | |
373 | if (!jz4740_codec->base) | |
363 | base = devm_request_and_ioremap(&pdev->dev, mem); | |
364 | if (!base) | |
374 | 365 | return -EBUSY; |
375 | 366 | |
367 | jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | |
368 | &jz4740_codec_regmap_config); | |
369 | if (IS_ERR(jz4740_codec->regmap)) | |
370 | return PTR_ERR(jz4740_codec->regmap); | |
371 | ||
376 | 372 | platform_set_drvdata(pdev, jz4740_codec); |
377 | 373 | |
378 | 374 | ret = snd_soc_register_codec(&pdev->dev, |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9