diff options
Diffstat (limited to 'sound/aoa/codecs/tas.c')
-rw-r--r-- | sound/aoa/codecs/tas.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 008e0f85097d..f0ebc971c686 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c | |||
@@ -82,7 +82,7 @@ MODULE_DESCRIPTION("tas codec driver for snd-aoa"); | |||
82 | 82 | ||
83 | struct tas { | 83 | struct tas { |
84 | struct aoa_codec codec; | 84 | struct aoa_codec codec; |
85 | struct i2c_client i2c; | 85 | struct i2c_client *i2c; |
86 | u32 mute_l:1, mute_r:1 , | 86 | u32 mute_l:1, mute_r:1 , |
87 | controls_created:1 , | 87 | controls_created:1 , |
88 | drc_enabled:1, | 88 | drc_enabled:1, |
@@ -108,9 +108,9 @@ static struct tas *codec_to_tas(struct aoa_codec *codec) | |||
108 | static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data) | 108 | static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data) |
109 | { | 109 | { |
110 | if (len == 1) | 110 | if (len == 1) |
111 | return i2c_smbus_write_byte_data(&tas->i2c, reg, *data); | 111 | return i2c_smbus_write_byte_data(tas->i2c, reg, *data); |
112 | else | 112 | else |
113 | return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data); | 113 | return i2c_smbus_write_i2c_block_data(tas->i2c, reg, len, data); |
114 | } | 114 | } |
115 | 115 | ||
116 | static void tas3004_set_drc(struct tas *tas) | 116 | static void tas3004_set_drc(struct tas *tas) |
@@ -882,12 +882,34 @@ static void tas_exit_codec(struct aoa_codec *codec) | |||
882 | } | 882 | } |
883 | 883 | ||
884 | 884 | ||
885 | static struct i2c_driver tas_driver; | ||
886 | |||
887 | static int tas_create(struct i2c_adapter *adapter, | 885 | static int tas_create(struct i2c_adapter *adapter, |
888 | struct device_node *node, | 886 | struct device_node *node, |
889 | int addr) | 887 | int addr) |
890 | { | 888 | { |
889 | struct i2c_board_info info; | ||
890 | struct i2c_client *client; | ||
891 | |||
892 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
893 | strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE); | ||
894 | info.addr = addr; | ||
895 | info.platform_data = node; | ||
896 | |||
897 | client = i2c_new_device(adapter, &info); | ||
898 | if (!client) | ||
899 | return -ENODEV; | ||
900 | |||
901 | /* | ||
902 | * Let i2c-core delete that device on driver removal. | ||
903 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
904 | */ | ||
905 | list_add_tail(&client->detected, &client->driver->clients); | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static int tas_i2c_probe(struct i2c_client *client, | ||
910 | const struct i2c_device_id *id) | ||
911 | { | ||
912 | struct device_node *node = client->dev.platform_data; | ||
891 | struct tas *tas; | 913 | struct tas *tas; |
892 | 914 | ||
893 | tas = kzalloc(sizeof(struct tas), GFP_KERNEL); | 915 | tas = kzalloc(sizeof(struct tas), GFP_KERNEL); |
@@ -896,17 +918,11 @@ static int tas_create(struct i2c_adapter *adapter, | |||
896 | return -ENOMEM; | 918 | return -ENOMEM; |
897 | 919 | ||
898 | mutex_init(&tas->mtx); | 920 | mutex_init(&tas->mtx); |
899 | tas->i2c.driver = &tas_driver; | 921 | tas->i2c = client; |
900 | tas->i2c.adapter = adapter; | 922 | i2c_set_clientdata(client, tas); |
901 | tas->i2c.addr = addr; | 923 | |
902 | /* seems that half is a saner default */ | 924 | /* seems that half is a saner default */ |
903 | tas->drc_range = TAS3004_DRC_MAX / 2; | 925 | tas->drc_range = TAS3004_DRC_MAX / 2; |
904 | strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE); | ||
905 | |||
906 | if (i2c_attach_client(&tas->i2c)) { | ||
907 | printk(KERN_ERR PFX "failed to attach to i2c\n"); | ||
908 | goto fail; | ||
909 | } | ||
910 | 926 | ||
911 | strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); | 927 | strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); |
912 | tas->codec.owner = THIS_MODULE; | 928 | tas->codec.owner = THIS_MODULE; |
@@ -915,14 +931,12 @@ static int tas_create(struct i2c_adapter *adapter, | |||
915 | tas->codec.node = of_node_get(node); | 931 | tas->codec.node = of_node_get(node); |
916 | 932 | ||
917 | if (aoa_codec_register(&tas->codec)) { | 933 | if (aoa_codec_register(&tas->codec)) { |
918 | goto detach; | 934 | goto fail; |
919 | } | 935 | } |
920 | printk(KERN_DEBUG | 936 | printk(KERN_DEBUG |
921 | "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", | 937 | "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", |
922 | addr, node->full_name); | 938 | (unsigned int)client->addr, node->full_name); |
923 | return 0; | 939 | return 0; |
924 | detach: | ||
925 | i2c_detach_client(&tas->i2c); | ||
926 | fail: | 940 | fail: |
927 | mutex_destroy(&tas->mtx); | 941 | mutex_destroy(&tas->mtx); |
928 | kfree(tas); | 942 | kfree(tas); |
@@ -970,14 +984,11 @@ static int tas_i2c_attach(struct i2c_adapter *adapter) | |||
970 | return -ENODEV; | 984 | return -ENODEV; |
971 | } | 985 | } |
972 | 986 | ||
973 | static int tas_i2c_detach(struct i2c_client *client) | 987 | static int tas_i2c_remove(struct i2c_client *client) |
974 | { | 988 | { |
975 | struct tas *tas = container_of(client, struct tas, i2c); | 989 | struct tas *tas = i2c_get_clientdata(client); |
976 | int err; | ||
977 | u8 tmp = TAS_ACR_ANALOG_PDOWN; | 990 | u8 tmp = TAS_ACR_ANALOG_PDOWN; |
978 | 991 | ||
979 | if ((err = i2c_detach_client(client))) | ||
980 | return err; | ||
981 | aoa_codec_unregister(&tas->codec); | 992 | aoa_codec_unregister(&tas->codec); |
982 | of_node_put(tas->codec.node); | 993 | of_node_put(tas->codec.node); |
983 | 994 | ||
@@ -989,13 +1000,20 @@ static int tas_i2c_detach(struct i2c_client *client) | |||
989 | return 0; | 1000 | return 0; |
990 | } | 1001 | } |
991 | 1002 | ||
1003 | static const struct i2c_device_id tas_i2c_id[] = { | ||
1004 | { "aoa_codec_tas", 0 }, | ||
1005 | { } | ||
1006 | }; | ||
1007 | |||
992 | static struct i2c_driver tas_driver = { | 1008 | static struct i2c_driver tas_driver = { |
993 | .driver = { | 1009 | .driver = { |
994 | .name = "aoa_codec_tas", | 1010 | .name = "aoa_codec_tas", |
995 | .owner = THIS_MODULE, | 1011 | .owner = THIS_MODULE, |
996 | }, | 1012 | }, |
997 | .attach_adapter = tas_i2c_attach, | 1013 | .attach_adapter = tas_i2c_attach, |
998 | .detach_client = tas_i2c_detach, | 1014 | .probe = tas_i2c_probe, |
1015 | .remove = tas_i2c_remove, | ||
1016 | .id_table = tas_i2c_id, | ||
999 | }; | 1017 | }; |
1000 | 1018 | ||
1001 | static int __init tas_init(void) | 1019 | static int __init tas_init(void) |