diff options
Diffstat (limited to 'sound/soc/codecs/jz4740.c')
-rw-r--r-- | sound/soc/codecs/jz4740.c | 116 |
1 files changed, 26 insertions, 90 deletions
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 66557de1e4fe..16253ec9b022 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -74,29 +74,22 @@ static const uint32_t jz4740_codec_regs[] = { | |||
74 | struct jz4740_codec { | 74 | struct jz4740_codec { |
75 | void __iomem *base; | 75 | void __iomem *base; |
76 | struct resource *mem; | 76 | struct resource *mem; |
77 | |||
78 | uint32_t reg_cache[2]; | ||
79 | struct snd_soc_codec codec; | ||
80 | }; | 77 | }; |
81 | 78 | ||
82 | static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec) | ||
83 | { | ||
84 | return container_of(codec, struct jz4740_codec, codec); | ||
85 | } | ||
86 | |||
87 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, | 79 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, |
88 | unsigned int reg) | 80 | unsigned int reg) |
89 | { | 81 | { |
90 | struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); | 82 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); |
91 | return readl(jz4740_codec->base + (reg << 2)); | 83 | return readl(jz4740_codec->base + (reg << 2)); |
92 | } | 84 | } |
93 | 85 | ||
94 | static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, | 86 | static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, |
95 | unsigned int val) | 87 | unsigned int val) |
96 | { | 88 | { |
97 | struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); | 89 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); |
90 | u32 *cache = codec->reg_cache; | ||
98 | 91 | ||
99 | jz4740_codec->reg_cache[reg] = val; | 92 | cache[reg] = val; |
100 | writel(val, jz4740_codec->base + (reg << 2)); | 93 | writel(val, jz4740_codec->base + (reg << 2)); |
101 | 94 | ||
102 | return 0; | 95 | return 0; |
@@ -172,8 +165,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, | |||
172 | { | 165 | { |
173 | uint32_t val; | 166 | uint32_t val; |
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 167 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
175 | struct snd_soc_device *socdev = rtd->socdev; | 168 | struct snd_soc_codec *codec =rtd->codec; |
176 | struct snd_soc_codec *codec = socdev->card->codec; | ||
177 | 169 | ||
178 | switch (params_rate(params)) { | 170 | switch (params_rate(params)) { |
179 | case 8000: | 171 | case 8000: |
@@ -219,8 +211,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = { | |||
219 | .hw_params = jz4740_codec_hw_params, | 211 | .hw_params = jz4740_codec_hw_params, |
220 | }; | 212 | }; |
221 | 213 | ||
222 | struct snd_soc_dai jz4740_codec_dai = { | 214 | static struct snd_soc_dai_driver jz4740_codec_dai = { |
223 | .name = "jz4740", | 215 | .name = "jz4740-hifi", |
224 | .playback = { | 216 | .playback = { |
225 | .stream_name = "Playback", | 217 | .stream_name = "Playback", |
226 | .channels_min = 2, | 218 | .channels_min = 2, |
@@ -238,7 +230,6 @@ struct snd_soc_dai jz4740_codec_dai = { | |||
238 | .ops = &jz4740_codec_dai_ops, | 230 | .ops = &jz4740_codec_dai_ops, |
239 | .symmetric_rates = 1, | 231 | .symmetric_rates = 1, |
240 | }; | 232 | }; |
241 | EXPORT_SYMBOL_GPL(jz4740_codec_dai); | ||
242 | 233 | ||
243 | static void jz4740_codec_wakeup(struct snd_soc_codec *codec) | 234 | static void jz4740_codec_wakeup(struct snd_soc_codec *codec) |
244 | { | 235 | { |
@@ -302,23 +293,10 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
302 | return 0; | 293 | return 0; |
303 | } | 294 | } |
304 | 295 | ||
305 | static struct snd_soc_codec *jz4740_codec_codec; | 296 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) |
306 | |||
307 | static int jz4740_codec_dev_probe(struct platform_device *pdev) | ||
308 | { | 297 | { |
309 | int ret; | 298 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, |
310 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 299 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
311 | struct snd_soc_codec *codec = jz4740_codec_codec; | ||
312 | |||
313 | BUG_ON(!codec); | ||
314 | |||
315 | socdev->card->codec = codec; | ||
316 | |||
317 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
318 | if (ret) { | ||
319 | dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret); | ||
320 | return ret; | ||
321 | } | ||
322 | 300 | ||
323 | snd_soc_add_controls(codec, jz4740_codec_controls, | 301 | snd_soc_add_controls(codec, jz4740_codec_controls, |
324 | ARRAY_SIZE(jz4740_codec_controls)); | 302 | ARRAY_SIZE(jz4740_codec_controls)); |
@@ -331,34 +309,27 @@ static int jz4740_codec_dev_probe(struct platform_device *pdev) | |||
331 | 309 | ||
332 | snd_soc_dapm_new_widgets(codec); | 310 | snd_soc_dapm_new_widgets(codec); |
333 | 311 | ||
312 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
313 | |||
334 | return 0; | 314 | return 0; |
335 | } | 315 | } |
336 | 316 | ||
337 | static int jz4740_codec_dev_remove(struct platform_device *pdev) | 317 | static int jz4740_codec_dev_remove(struct snd_soc_codec *codec) |
338 | { | 318 | { |
339 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 319 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); |
340 | |||
341 | snd_soc_free_pcms(socdev); | ||
342 | snd_soc_dapm_free(socdev); | ||
343 | 320 | ||
344 | return 0; | 321 | return 0; |
345 | } | 322 | } |
346 | 323 | ||
347 | #ifdef CONFIG_PM_SLEEP | 324 | #ifdef CONFIG_PM_SLEEP |
348 | 325 | ||
349 | static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state) | 326 | static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state) |
350 | { | 327 | { |
351 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
352 | struct snd_soc_codec *codec = socdev->card->codec; | ||
353 | |||
354 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); | 328 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); |
355 | } | 329 | } |
356 | 330 | ||
357 | static int jz4740_codec_resume(struct platform_device *pdev) | 331 | static int jz4740_codec_resume(struct snd_soc_codec *codec) |
358 | { | 332 | { |
359 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
360 | struct snd_soc_codec *codec = socdev->card->codec; | ||
361 | |||
362 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 333 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
363 | } | 334 | } |
364 | 335 | ||
@@ -367,19 +338,23 @@ static int jz4740_codec_resume(struct platform_device *pdev) | |||
367 | #define jz4740_codec_resume NULL | 338 | #define jz4740_codec_resume NULL |
368 | #endif | 339 | #endif |
369 | 340 | ||
370 | struct snd_soc_codec_device soc_codec_dev_jz4740_codec = { | 341 | static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { |
371 | .probe = jz4740_codec_dev_probe, | 342 | .probe = jz4740_codec_dev_probe, |
372 | .remove = jz4740_codec_dev_remove, | 343 | .remove = jz4740_codec_dev_remove, |
373 | .suspend = jz4740_codec_suspend, | 344 | .suspend = jz4740_codec_suspend, |
374 | .resume = jz4740_codec_resume, | 345 | .resume = jz4740_codec_resume, |
346 | .read = jz4740_codec_read, | ||
347 | .write = jz4740_codec_write, | ||
348 | .set_bias_level = jz4740_codec_set_bias_level, | ||
349 | .reg_cache_default = jz4740_codec_regs, | ||
350 | .reg_word_size = sizeof(u32), | ||
351 | .reg_cache_size = 2, | ||
375 | }; | 352 | }; |
376 | EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec); | ||
377 | 353 | ||
378 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) | 354 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) |
379 | { | 355 | { |
380 | int ret; | 356 | int ret; |
381 | struct jz4740_codec *jz4740_codec; | 357 | struct jz4740_codec *jz4740_codec; |
382 | struct snd_soc_codec *codec; | ||
383 | struct resource *mem; | 358 | struct resource *mem; |
384 | 359 | ||
385 | jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL); | 360 | jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL); |
@@ -408,55 +383,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) | |||
408 | } | 383 | } |
409 | jz4740_codec->mem = mem; | 384 | jz4740_codec->mem = mem; |
410 | 385 | ||
411 | jz4740_codec_dai.dev = &pdev->dev; | ||
412 | |||
413 | codec = &jz4740_codec->codec; | ||
414 | |||
415 | codec->dev = &pdev->dev; | ||
416 | codec->name = "jz4740"; | ||
417 | codec->owner = THIS_MODULE; | ||
418 | |||
419 | codec->read = jz4740_codec_read; | ||
420 | codec->write = jz4740_codec_write; | ||
421 | codec->set_bias_level = jz4740_codec_set_bias_level; | ||
422 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
423 | |||
424 | codec->dai = &jz4740_codec_dai; | ||
425 | codec->num_dai = 1; | ||
426 | |||
427 | codec->reg_cache = jz4740_codec->reg_cache; | ||
428 | codec->reg_cache_size = 2; | ||
429 | memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs)); | ||
430 | |||
431 | mutex_init(&codec->mutex); | ||
432 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
433 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
434 | |||
435 | jz4740_codec_codec = codec; | ||
436 | |||
437 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | ||
438 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); | ||
439 | |||
440 | platform_set_drvdata(pdev, jz4740_codec); | 386 | platform_set_drvdata(pdev, jz4740_codec); |
441 | 387 | ||
442 | ret = snd_soc_register_codec(codec); | 388 | ret = snd_soc_register_codec(&pdev->dev, |
389 | &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); | ||
443 | if (ret) { | 390 | if (ret) { |
444 | dev_err(&pdev->dev, "Failed to register codec\n"); | 391 | dev_err(&pdev->dev, "Failed to register codec\n"); |
445 | goto err_iounmap; | 392 | goto err_iounmap; |
446 | } | 393 | } |
447 | 394 | ||
448 | ret = snd_soc_register_dai(&jz4740_codec_dai); | ||
449 | if (ret) { | ||
450 | dev_err(&pdev->dev, "Failed to register codec dai\n"); | ||
451 | goto err_unregister_codec; | ||
452 | } | ||
453 | |||
454 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
455 | |||
456 | return 0; | 395 | return 0; |
457 | 396 | ||
458 | err_unregister_codec: | ||
459 | snd_soc_unregister_codec(codec); | ||
460 | err_iounmap: | 397 | err_iounmap: |
461 | iounmap(jz4740_codec->base); | 398 | iounmap(jz4740_codec->base); |
462 | err_release_mem_region: | 399 | err_release_mem_region: |
@@ -472,8 +409,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev) | |||
472 | struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); | 409 | struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); |
473 | struct resource *mem = jz4740_codec->mem; | 410 | struct resource *mem = jz4740_codec->mem; |
474 | 411 | ||
475 | snd_soc_unregister_dai(&jz4740_codec_dai); | 412 | snd_soc_unregister_codec(&pdev->dev); |
476 | snd_soc_unregister_codec(&jz4740_codec->codec); | ||
477 | 413 | ||
478 | iounmap(jz4740_codec->base); | 414 | iounmap(jz4740_codec->base); |
479 | release_mem_region(mem->start, resource_size(mem)); | 415 | release_mem_region(mem->start, resource_size(mem)); |