diff options
-rw-r--r-- | sound/soc/codecs/ak4535.c | 110 | ||||
-rw-r--r-- | sound/soc/codecs/ak4535.h | 1 |
2 files changed, 54 insertions, 57 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 7da9f467b7b8..e512cd79d767 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -535,87 +535,85 @@ static struct snd_soc_device *ak4535_socdev; | |||
535 | 535 | ||
536 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 536 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
537 | 537 | ||
538 | #define I2C_DRIVERID_AK4535 0xfefe /* liam - need a proper id */ | 538 | static int ak4535_i2c_probe(struct i2c_client *i2c, |
539 | 539 | const struct i2c_device_id *id) | |
540 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | ||
541 | |||
542 | /* Magic definition of all other variables and things */ | ||
543 | I2C_CLIENT_INSMOD; | ||
544 | |||
545 | static struct i2c_driver ak4535_i2c_driver; | ||
546 | static struct i2c_client client_template; | ||
547 | |||
548 | /* If the i2c layer weren't so broken, we could pass this kind of data | ||
549 | around */ | ||
550 | static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind) | ||
551 | { | 540 | { |
552 | struct snd_soc_device *socdev = ak4535_socdev; | 541 | struct snd_soc_device *socdev = ak4535_socdev; |
553 | struct ak4535_setup_data *setup = socdev->codec_data; | ||
554 | struct snd_soc_codec *codec = socdev->codec; | 542 | struct snd_soc_codec *codec = socdev->codec; |
555 | struct i2c_client *i2c; | ||
556 | int ret; | 543 | int ret; |
557 | 544 | ||
558 | if (addr != setup->i2c_address) | ||
559 | return -ENODEV; | ||
560 | |||
561 | client_template.adapter = adap; | ||
562 | client_template.addr = addr; | ||
563 | |||
564 | i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); | ||
565 | if (i2c == NULL) | ||
566 | return -ENOMEM; | ||
567 | |||
568 | i2c_set_clientdata(i2c, codec); | 545 | i2c_set_clientdata(i2c, codec); |
569 | codec->control_data = i2c; | 546 | codec->control_data = i2c; |
570 | 547 | ||
571 | ret = i2c_attach_client(i2c); | ||
572 | if (ret < 0) { | ||
573 | printk(KERN_ERR "failed to attach codec at addr %x\n", addr); | ||
574 | goto err; | ||
575 | } | ||
576 | |||
577 | ret = ak4535_init(socdev); | 548 | ret = ak4535_init(socdev); |
578 | if (ret < 0) { | 549 | if (ret < 0) |
579 | printk(KERN_ERR "failed to initialise AK4535\n"); | 550 | printk(KERN_ERR "failed to initialise AK4535\n"); |
580 | goto err; | ||
581 | } | ||
582 | return ret; | ||
583 | 551 | ||
584 | err: | ||
585 | kfree(i2c); | ||
586 | return ret; | 552 | return ret; |
587 | } | 553 | } |
588 | 554 | ||
589 | static int ak4535_i2c_detach(struct i2c_client *client) | 555 | static int ak4535_i2c_remove(struct i2c_client *client) |
590 | { | 556 | { |
591 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 557 | struct snd_soc_codec *codec = i2c_get_clientdata(client); |
592 | i2c_detach_client(client); | ||
593 | kfree(codec->reg_cache); | 558 | kfree(codec->reg_cache); |
594 | kfree(client); | ||
595 | return 0; | 559 | return 0; |
596 | } | 560 | } |
597 | 561 | ||
598 | static int ak4535_i2c_attach(struct i2c_adapter *adap) | 562 | static const struct i2c_device_id ak4535_i2c_id[] = { |
599 | { | 563 | { "ak4535", 0 }, |
600 | return i2c_probe(adap, &addr_data, ak4535_codec_probe); | 564 | { } |
601 | } | 565 | }; |
566 | MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id); | ||
602 | 567 | ||
603 | /* corgi i2c codec control layer */ | ||
604 | static struct i2c_driver ak4535_i2c_driver = { | 568 | static struct i2c_driver ak4535_i2c_driver = { |
605 | .driver = { | 569 | .driver = { |
606 | .name = "AK4535 I2C Codec", | 570 | .name = "AK4535 I2C Codec", |
607 | .owner = THIS_MODULE, | 571 | .owner = THIS_MODULE, |
608 | }, | 572 | }, |
609 | .id = I2C_DRIVERID_AK4535, | 573 | .probe = ak4535_i2c_probe, |
610 | .attach_adapter = ak4535_i2c_attach, | 574 | .remove = ak4535_i2c_remove, |
611 | .detach_client = ak4535_i2c_detach, | 575 | .id_table = ak4535_i2c_id, |
612 | .command = NULL, | ||
613 | }; | 576 | }; |
614 | 577 | ||
615 | static struct i2c_client client_template = { | 578 | static int ak4535_add_i2c_device(struct platform_device *pdev, |
616 | .name = "AK4535", | 579 | const struct ak4535_setup_data *setup) |
617 | .driver = &ak4535_i2c_driver, | 580 | { |
618 | }; | 581 | struct i2c_board_info info; |
582 | struct i2c_adapter *adapter; | ||
583 | struct i2c_client *client; | ||
584 | int ret; | ||
585 | |||
586 | ret = i2c_add_driver(&ak4535_i2c_driver); | ||
587 | if (ret != 0) { | ||
588 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
589 | return ret; | ||
590 | } | ||
591 | |||
592 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
593 | info.addr = setup->i2c_address; | ||
594 | strlcpy(info.type, "ak4535", I2C_NAME_SIZE); | ||
595 | |||
596 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
597 | if (!adapter) { | ||
598 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
599 | setup->i2c_bus); | ||
600 | goto err_driver; | ||
601 | } | ||
602 | |||
603 | client = i2c_new_device(adapter, &info); | ||
604 | i2c_put_adapter(adapter); | ||
605 | if (!client) { | ||
606 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
607 | (unsigned int)info.addr); | ||
608 | goto err_driver; | ||
609 | } | ||
610 | |||
611 | return 0; | ||
612 | |||
613 | err_driver: | ||
614 | i2c_del_driver(&ak4535_i2c_driver); | ||
615 | return -ENODEV; | ||
616 | } | ||
619 | #endif | 617 | #endif |
620 | 618 | ||
621 | static int ak4535_probe(struct platform_device *pdev) | 619 | static int ak4535_probe(struct platform_device *pdev) |
@@ -648,12 +646,9 @@ static int ak4535_probe(struct platform_device *pdev) | |||
648 | ak4535_socdev = socdev; | 646 | ak4535_socdev = socdev; |
649 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 647 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
650 | if (setup->i2c_address) { | 648 | if (setup->i2c_address) { |
651 | normal_i2c[0] = setup->i2c_address; | ||
652 | codec->hw_write = (hw_write_t)i2c_master_send; | 649 | codec->hw_write = (hw_write_t)i2c_master_send; |
653 | codec->hw_read = (hw_read_t)i2c_master_recv; | 650 | codec->hw_read = (hw_read_t)i2c_master_recv; |
654 | ret = i2c_add_driver(&ak4535_i2c_driver); | 651 | ret = ak4535_add_i2c_device(pdev, setup); |
655 | if (ret != 0) | ||
656 | printk(KERN_ERR "can't add i2c driver"); | ||
657 | } | 652 | } |
658 | #else | 653 | #else |
659 | /* Add other interfaces here */ | 654 | /* Add other interfaces here */ |
@@ -678,6 +673,7 @@ static int ak4535_remove(struct platform_device *pdev) | |||
678 | snd_soc_free_pcms(socdev); | 673 | snd_soc_free_pcms(socdev); |
679 | snd_soc_dapm_free(socdev); | 674 | snd_soc_dapm_free(socdev); |
680 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 675 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
676 | i2c_unregister_device(codec->control_data); | ||
681 | i2c_del_driver(&ak4535_i2c_driver); | 677 | i2c_del_driver(&ak4535_i2c_driver); |
682 | #endif | 678 | #endif |
683 | kfree(codec->private_data); | 679 | kfree(codec->private_data); |
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h index e9fe30e2c056..c7a58703ea39 100644 --- a/sound/soc/codecs/ak4535.h +++ b/sound/soc/codecs/ak4535.h | |||
@@ -37,6 +37,7 @@ | |||
37 | #define AK4535_CACHEREGNUM 0x10 | 37 | #define AK4535_CACHEREGNUM 0x10 |
38 | 38 | ||
39 | struct ak4535_setup_data { | 39 | struct ak4535_setup_data { |
40 | int i2c_bus; | ||
40 | unsigned short i2c_address; | 41 | unsigned short i2c_address; |
41 | }; | 42 | }; |
42 | 43 | ||