diff options
Diffstat (limited to 'sound/aoa')
-rw-r--r-- | sound/aoa/codecs/onyx.c | 76 | ||||
-rw-r--r-- | sound/aoa/codecs/tas.c | 66 | ||||
-rw-r--r-- | sound/aoa/fabrics/layout.c | 8 | ||||
-rw-r--r-- | sound/aoa/soundbus/i2sbus/core.c | 8 |
4 files changed, 103 insertions, 55 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 15500b9d2da..84bb07d39a7 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -47,7 +47,7 @@ MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); struct onyx { /* cache registers 65 to 80, they are write-only! */ u8 cache[16]; - struct i2c_client i2c; + struct i2c_client *i2c; struct aoa_codec codec; u32 initialised:1, spdif_locked:1, @@ -72,7 +72,7 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) *value = onyx->cache[reg-FIRSTREGISTER]; return 0; } - v = i2c_smbus_read_byte_data(&onyx->i2c, reg); + v = i2c_smbus_read_byte_data(onyx->i2c, reg); if (v < 0) return -1; *value = (u8)v; @@ -84,7 +84,7 @@ static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value) { int result; - result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value); + result = i2c_smbus_write_byte_data(onyx->i2c, reg, value); if (!result) onyx->cache[reg-FIRSTREGISTER] = value; return result; @@ -996,12 +996,45 @@ static void onyx_exit_codec(struct aoa_codec *codec) onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx); } -static struct i2c_driver onyx_driver; - static int onyx_create(struct i2c_adapter *adapter, struct device_node *node, int addr) { + struct i2c_board_info info; + struct i2c_client *client; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE); + info.addr = addr; + info.platform_data = node; + client = i2c_new_device(adapter, &info); + if (!client) + return -ENODEV; + + /* + * We know the driver is already loaded, so the device should be + * already bound. If not it means binding failed, which suggests + * the device doesn't really exist and should be deleted. + * Ideally this would be replaced by better checks _before_ + * instantiating the device. + */ + if (!client->driver) { + i2c_unregister_device(client); + return -ENODEV; + } + + /* + * Let i2c-core delete that device on driver removal. + * This is safe because i2c-core holds the core_lock mutex for us. + */ + list_add_tail(&client->detected, &client->driver->clients); + return 0; +} + +static int onyx_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *node = client->dev.platform_data; struct onyx *onyx; u8 dummy; @@ -1011,20 +1044,12 @@ static int onyx_create(struct i2c_adapter *adapter, return -ENOMEM; mutex_init(&onyx->mutex); - onyx->i2c.driver = &onyx_driver; - onyx->i2c.adapter = adapter; - onyx->i2c.addr = addr & 0x7f; - strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE); - - if (i2c_attach_client(&onyx->i2c)) { - printk(KERN_ERR PFX "failed to attach to i2c\n"); - goto fail; - } + onyx->i2c = client; + i2c_set_clientdata(client, onyx); /* we try to read from register ONYX_REG_CONTROL * to check if the codec is present */ if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) { - i2c_detach_client(&onyx->i2c); printk(KERN_ERR PFX "failed to read control register\n"); goto fail; } @@ -1036,14 +1061,14 @@ static int onyx_create(struct i2c_adapter *adapter, onyx->codec.node = of_node_get(node); if (aoa_codec_register(&onyx->codec)) { - i2c_detach_client(&onyx->i2c); goto fail; } printk(KERN_DEBUG PFX "created and attached onyx instance\n"); return 0; fail: + i2c_set_clientdata(client, NULL); kfree(onyx); - return -EINVAL; + return -ENODEV; } static int onyx_i2c_attach(struct i2c_adapter *adapter) @@ -1080,28 +1105,33 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter) return onyx_create(adapter, NULL, 0x47); } -static int onyx_i2c_detach(struct i2c_client *client) +static int onyx_i2c_remove(struct i2c_client *client) { - struct onyx *onyx = container_of(client, struct onyx, i2c); - int err; + struct onyx *onyx = i2c_get_clientdata(client); - if ((err = i2c_detach_client(client))) - return err; aoa_codec_unregister(&onyx->codec); of_node_put(onyx->codec.node); if (onyx->codec_info) kfree(onyx->codec_info); + i2c_set_clientdata(client, onyx); kfree(onyx); return 0; } +static const struct i2c_device_id onyx_i2c_id[] = { + { "aoa_codec_onyx", 0 }, + { } +}; + static struct i2c_driver onyx_driver = { .driver = { .name = "aoa_codec_onyx", .owner = THIS_MODULE, }, .attach_adapter = onyx_i2c_attach, - .detach_client = onyx_i2c_detach, + .probe = onyx_i2c_probe, + .remove = onyx_i2c_remove, + .id_table = onyx_i2c_id, }; static int __init onyx_init(void) diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 008e0f85097..f0ebc971c68 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"); struct tas { struct aoa_codec codec; - struct i2c_client i2c; + struct i2c_client *i2c; u32 mute_l:1, mute_r:1 , controls_created:1 , drc_enabled:1, @@ -108,9 +108,9 @@ static struct tas *codec_to_tas(struct aoa_codec *codec) static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data) { if (len == 1) - return i2c_smbus_write_byte_data(&tas->i2c, reg, *data); + return i2c_smbus_write_byte_data(tas->i2c, reg, *data); else - return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data); + return i2c_smbus_write_i2c_block_data(tas->i2c, reg, len, data); } static void tas3004_set_drc(struct tas *tas) @@ -882,12 +882,34 @@ static void tas_exit_codec(struct aoa_codec *codec) } -static struct i2c_driver tas_driver; - static int tas_create(struct i2c_adapter *adapter, struct device_node *node, int addr) { + struct i2c_board_info info; + struct i2c_client *client; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE); + info.addr = addr; + info.platform_data = node; + + client = i2c_new_device(adapter, &info); + if (!client) + return -ENODEV; + + /* + * Let i2c-core delete that device on driver removal. + * This is safe because i2c-core holds the core_lock mutex for us. + */ + list_add_tail(&client->detected, &client->driver->clients); + return 0; +} + +static int tas_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *node = client->dev.platform_data; struct tas *tas; tas = kzalloc(sizeof(struct tas), GFP_KERNEL); @@ -896,17 +918,11 @@ static int tas_create(struct i2c_adapter *adapter, return -ENOMEM; mutex_init(&tas->mtx); - tas->i2c.driver = &tas_driver; - tas->i2c.adapter = adapter; - tas->i2c.addr = addr; + tas->i2c = client; + i2c_set_clientdata(client, tas); + /* seems that half is a saner default */ tas->drc_range = TAS3004_DRC_MAX / 2; - strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE); - - if (i2c_attach_client(&tas->i2c)) { - printk(KERN_ERR PFX "failed to attach to i2c\n"); - goto fail; - } strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); tas->codec.owner = THIS_MODULE; @@ -915,14 +931,12 @@ static int tas_create(struct i2c_adapter *adapter, tas->codec.node = of_node_get(node); if (aoa_codec_register(&tas->codec)) { - goto detach; + goto fail; } printk(KERN_DEBUG "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", - addr, node->full_name); + (unsigned int)client->addr, node->full_name); return 0; - detach: - i2c_detach_client(&tas->i2c); fail: mutex_destroy(&tas->mtx); kfree(tas); @@ -970,14 +984,11 @@ static int tas_i2c_attach(struct i2c_adapter *adapter) return -ENODEV; } -static int tas_i2c_detach(struct i2c_client *client) +static int tas_i2c_remove(struct i2c_client *client) { - struct tas *tas = container_of(client, struct tas, i2c); - int err; + struct tas *tas = i2c_get_clientdata(client); u8 tmp = TAS_ACR_ANALOG_PDOWN; - if ((err = i2c_detach_client(client))) - return err; aoa_codec_unregister(&tas->codec); of_node_put(tas->codec.node); @@ -989,13 +1000,20 @@ static int tas_i2c_detach(struct i2c_client *client) return 0; } +static const struct i2c_device_id tas_i2c_id[] = { + { "aoa_codec_tas", 0 }, + { } +}; + static struct i2c_driver tas_driver = { .driver = { .name = "aoa_codec_tas", .owner = THIS_MODULE, }, .attach_adapter = tas_i2c_attach, - .detach_client = tas_i2c_detach, + .probe = tas_i2c_probe, + .remove = tas_i2c_remove, + .id_table = tas_i2c_id, }; static int __init tas_init(void) diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index fbf5c933baa..586965f9605 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) } ldev->selfptr_headphone.ptr = ldev; ldev->selfptr_lineout.ptr = ldev; - sdev->ofdev.dev.driver_data = ldev; + dev_set_drvdata(&sdev->ofdev.dev, ldev); list_add(&ldev->list, &layouts_list); layouts_list_items++; @@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) static int aoa_fabric_layout_remove(struct soundbus_dev *sdev) { - struct layout_dev *ldev = sdev->ofdev.dev.driver_data; + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev); int i; for (i=0; i<MAX_CODECS_PER_BUS; i++) { @@ -1114,7 +1114,7 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev) #ifdef CONFIG_PM static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state) { - struct layout_dev *ldev = sdev->ofdev.dev.driver_data; + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev); if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_off(&ldev->gpio); @@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta static int aoa_fabric_layout_resume(struct soundbus_dev *sdev) { - struct layout_dev *ldev = sdev->ofdev.dev.driver_data; + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev); if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_restore(&ldev->gpio); diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 418c84c99d6..4e3b819d499 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) return -ENODEV; } - dev->ofdev.dev.driver_data = control; + dev_set_drvdata(&dev->ofdev.dev, control); return 0; } static int i2sbus_remove(struct macio_dev* dev) { - struct i2sbus_control *control = dev->ofdev.dev.driver_data; + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); struct i2sbus_dev *i2sdev, *tmp; list_for_each_entry_safe(i2sdev, tmp, &control->list, item) @@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev) #ifdef CONFIG_PM static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) { - struct i2sbus_control *control = dev->ofdev.dev.driver_data; + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); struct codec_info_item *cii; struct i2sbus_dev* i2sdev; int err, ret = 0; @@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) static int i2sbus_resume(struct macio_dev* dev) { - struct i2sbus_control *control = dev->ofdev.dev.driver_data; + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); struct codec_info_item *cii; struct i2sbus_dev* i2sdev; int err, ret = 0; |