aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/jz4740.c')
-rw-r--r--sound/soc/codecs/jz4740.c116
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[] = {
74struct jz4740_codec { 74struct 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
82static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
83{
84 return container_of(codec, struct jz4740_codec, codec);
85}
86
87static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, 79static 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
94static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, 86static 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
222struct snd_soc_dai jz4740_codec_dai = { 214static 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};
241EXPORT_SYMBOL_GPL(jz4740_codec_dai);
242 233
243static void jz4740_codec_wakeup(struct snd_soc_codec *codec) 234static 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
305static struct snd_soc_codec *jz4740_codec_codec; 296static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
306
307static 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
337static int jz4740_codec_dev_remove(struct platform_device *pdev) 317static 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
349static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state) 326static 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
357static int jz4740_codec_resume(struct platform_device *pdev) 331static 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
370struct snd_soc_codec_device soc_codec_dev_jz4740_codec = { 341static 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};
376EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
377 353
378static int __devinit jz4740_codec_probe(struct platform_device *pdev) 354static 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
458err_unregister_codec:
459 snd_soc_unregister_codec(codec);
460err_iounmap: 397err_iounmap:
461 iounmap(jz4740_codec->base); 398 iounmap(jz4740_codec->base);
462err_release_mem_region: 399err_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));