diff options
Diffstat (limited to 'sound/soc/codecs/ak4535.c')
-rw-r--r-- | sound/soc/codecs/ak4535.c | 98 |
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 */ |
33 | struct ak4535_priv { | 32 | struct 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 | */ |
41 | static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { | 40 | static 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 | ||
58 | static 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 | |||
48 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; | 68 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; |
49 | static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; | 69 | static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; |
50 | static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; | 70 | static 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 | ||
416 | static 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 | |||
397 | static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { | 428 | static 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) | ||
413 | static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | 440 | static __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 | ||
432 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) | 468 | static __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 | ||
444 | static struct i2c_driver ak4535_i2c_driver = { | 483 | static 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 | ||
455 | static int __init ak4535_modinit(void) | 493 | module_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 | } | ||
467 | module_init(ak4535_modinit); | ||
468 | |||
469 | static 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 | } | ||
475 | module_exit(ak4535_exit); | ||
476 | 494 | ||
477 | MODULE_DESCRIPTION("Soc AK4535 driver"); | 495 | MODULE_DESCRIPTION("Soc AK4535 driver"); |
478 | MODULE_AUTHOR("Richard Purdie"); | 496 | MODULE_AUTHOR("Richard Purdie"); |