aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4535.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ak4535.c')
-rw-r--r--sound/soc/codecs/ak4535.c98
1 files changed, 58 insertions, 40 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 9e809e05d066..838ae8b22b50 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -27,24 +28,43 @@
27 28
28#include "ak4535.h" 29#include "ak4535.h"
29 30
30#define AK4535_VERSION "0.3"
31
32/* codec private data */ 31/* codec private data */
33struct ak4535_priv { 32struct ak4535_priv {
33 struct regmap *regmap;
34 unsigned int sysclk; 34 unsigned int sysclk;
35 enum snd_soc_control_type control_type;
36}; 35};
37 36
38/* 37/*
39 * ak4535 register cache 38 * ak4535 register cache
40 */ 39 */
41static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { 40static const struct reg_default ak4535_reg_defaults[] = {
42 0x00, 0x80, 0x00, 0x03, 41 { 0, 0x00 },
43 0x02, 0x00, 0x11, 0x01, 42 { 1, 0x80 },
44 0x00, 0x40, 0x36, 0x10, 43 { 2, 0x00 },
45 0x00, 0x00, 0x57, 0x00, 44 { 3, 0x03 },
45 { 4, 0x02 },
46 { 5, 0x00 },
47 { 6, 0x11 },
48 { 7, 0x01 },
49 { 8, 0x00 },
50 { 9, 0x40 },
51 { 10, 0x36 },
52 { 11, 0x10 },
53 { 12, 0x00 },
54 { 13, 0x00 },
55 { 14, 0x57 },
46}; 56};
47 57
58static bool ak4535_volatile(struct device *dev, unsigned int reg)
59{
60 switch (reg) {
61 case AK4535_STATUS:
62 return true;
63 default:
64 return false;
65 }
66}
67
48static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 68static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
49static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; 69static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
50static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; 70static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
372 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 392 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
373 int ret; 393 int ret;
374 394
375 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 395 codec->control_data = ak4535->regmap;
376 396 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
377 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
378 if (ret < 0) { 397 if (ret < 0) {
379 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 398 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
380 return ret; 399 return ret;
@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
382 /* power on device */ 401 /* power on device */
383 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 402 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
384 403
385 snd_soc_add_controls(codec, ak4535_snd_controls, 404 snd_soc_add_codec_controls(codec, ak4535_snd_controls,
386 ARRAY_SIZE(ak4535_snd_controls)); 405 ARRAY_SIZE(ak4535_snd_controls));
387 return 0; 406 return 0;
388} 407}
@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
394 return 0; 413 return 0;
395} 414}
396 415
416static const struct regmap_config ak4535_regmap = {
417 .reg_bits = 8,
418 .val_bits = 8,
419
420 .max_register = AK4535_STATUS,
421 .volatile_reg = ak4535_volatile,
422
423 .cache_type = REGCACHE_RBTREE,
424 .reg_defaults = ak4535_reg_defaults,
425 .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
426};
427
397static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { 428static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
398 .probe = ak4535_probe, 429 .probe = ak4535_probe,
399 .remove = ak4535_remove, 430 .remove = ak4535_remove,
400 .suspend = ak4535_suspend, 431 .suspend = ak4535_suspend,
401 .resume = ak4535_resume, 432 .resume = ak4535_resume,
402 .set_bias_level = ak4535_set_bias_level, 433 .set_bias_level = ak4535_set_bias_level,
403 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
404 .reg_word_size = sizeof(u8),
405 .reg_cache_default = ak4535_reg,
406 .dapm_widgets = ak4535_dapm_widgets, 434 .dapm_widgets = ak4535_dapm_widgets,
407 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), 435 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
408 .dapm_routes = ak4535_audio_map, 436 .dapm_routes = ak4535_audio_map,
409 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), 437 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
410}; 438};
411 439
412#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
413static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, 440static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
414 const struct i2c_device_id *id) 441 const struct i2c_device_id *id)
415{ 442{
@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
421 if (ak4535 == NULL) 448 if (ak4535 == NULL)
422 return -ENOMEM; 449 return -ENOMEM;
423 450
451 ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
452 if (IS_ERR(ak4535->regmap)) {
453 ret = PTR_ERR(ak4535->regmap);
454 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
455 return ret;
456 }
457
424 i2c_set_clientdata(i2c, ak4535); 458 i2c_set_clientdata(i2c, ak4535);
425 ak4535->control_type = SND_SOC_I2C;
426 459
427 ret = snd_soc_register_codec(&i2c->dev, 460 ret = snd_soc_register_codec(&i2c->dev,
428 &soc_codec_dev_ak4535, &ak4535_dai, 1); 461 &soc_codec_dev_ak4535, &ak4535_dai, 1);
462 if (ret != 0)
463 regmap_exit(ak4535->regmap);
464
429 return ret; 465 return ret;
430} 466}
431 467
432static __devexit int ak4535_i2c_remove(struct i2c_client *client) 468static __devexit int ak4535_i2c_remove(struct i2c_client *client)
433{ 469{
470 struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
471
434 snd_soc_unregister_codec(&client->dev); 472 snd_soc_unregister_codec(&client->dev);
473 regmap_exit(ak4535->regmap);
435 return 0; 474 return 0;
436} 475}
437 476
@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
443 482
444static struct i2c_driver ak4535_i2c_driver = { 483static struct i2c_driver ak4535_i2c_driver = {
445 .driver = { 484 .driver = {
446 .name = "ak4535-codec", 485 .name = "ak4535",
447 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
448 }, 487 },
449 .probe = ak4535_i2c_probe, 488 .probe = ak4535_i2c_probe,
450 .remove = __devexit_p(ak4535_i2c_remove), 489 .remove = __devexit_p(ak4535_i2c_remove),
451 .id_table = ak4535_i2c_id, 490 .id_table = ak4535_i2c_id,
452}; 491};
453#endif
454 492
455static int __init ak4535_modinit(void) 493module_i2c_driver(ak4535_i2c_driver);
456{
457 int ret = 0;
458#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
459 ret = i2c_add_driver(&ak4535_i2c_driver);
460 if (ret != 0) {
461 printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
462 ret);
463 }
464#endif
465 return ret;
466}
467module_init(ak4535_modinit);
468
469static void __exit ak4535_exit(void)
470{
471#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
472 i2c_del_driver(&ak4535_i2c_driver);
473#endif
474}
475module_exit(ak4535_exit);
476 494
477MODULE_DESCRIPTION("Soc AK4535 driver"); 495MODULE_DESCRIPTION("Soc AK4535 driver");
478MODULE_AUTHOR("Richard Purdie"); 496MODULE_AUTHOR("Richard Purdie");