Commit 2a557a86 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/hda-unbind' into for-next

parents 8f88f025 b2a0bafa
......@@ -278,7 +278,8 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
void *device_data, struct snd_device_ops *ops);
int snd_device_register(struct snd_card *card, void *device_data);
int snd_device_register_all(struct snd_card *card);
int snd_device_disconnect_all(struct snd_card *card);
void snd_device_disconnect(struct snd_card *card, void *device_data);
void snd_device_disconnect_all(struct snd_card *card);
void snd_device_free(struct snd_card *card, void *device_data);
void snd_device_free_all(struct snd_card *card);
......
......@@ -71,7 +71,7 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
}
EXPORT_SYMBOL(snd_device_new);
static int __snd_device_disconnect(struct snd_device *dev)
static void __snd_device_disconnect(struct snd_device *dev)
{
if (dev->state == SNDRV_DEV_REGISTERED) {
if (dev->ops->dev_disconnect &&
......@@ -79,7 +79,6 @@ static int __snd_device_disconnect(struct snd_device *dev)
dev_err(dev->card->dev, "device disconnect failure\n");
dev->state = SNDRV_DEV_DISCONNECTED;
}
return 0;
}
static void __snd_device_free(struct snd_device *dev)
......@@ -106,6 +105,34 @@ static struct snd_device *look_for_dev(struct snd_card *card, void *device_data)
return NULL;
}
/**
* snd_device_disconnect - disconnect the device
* @card: the card instance
* @device_data: the data pointer to disconnect
*
* Turns the device into the disconnection state, invoking
* dev_disconnect callback, if the device was already registered.
*
* Usually called from snd_card_disconnect().
*
* Return: Zero if successful, or a negative error code on failure or if the
* device not found.
*/
void snd_device_disconnect(struct snd_card *card, void *device_data)
{
struct snd_device *dev;
if (snd_BUG_ON(!card || !device_data))
return;
dev = look_for_dev(card, device_data);
if (dev)
__snd_device_disconnect(dev);
else
dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n",
device_data, __builtin_return_address(0));
}
EXPORT_SYMBOL_GPL(snd_device_disconnect);
/**
* snd_device_free - release the device from the card
* @card: the card instance
......@@ -193,18 +220,14 @@ int snd_device_register_all(struct snd_card *card)
* disconnect all the devices on the card.
* called from init.c
*/
int snd_device_disconnect_all(struct snd_card *card)
void snd_device_disconnect_all(struct snd_card *card)
{
struct snd_device *dev;
int err = 0;
if (snd_BUG_ON(!card))
return -ENXIO;
list_for_each_entry_reverse(dev, &card->devices, list) {
if (__snd_device_disconnect(dev) < 0)
err = -ENXIO;
}
return err;
return;
list_for_each_entry_reverse(dev, &card->devices, list)
__snd_device_disconnect(dev);
}
/*
......
......@@ -400,7 +400,6 @@ static const struct file_operations snd_shutdown_f_ops =
int snd_card_disconnect(struct snd_card *card)
{
struct snd_monitor_file *mfile;
int err;
if (!card)
return -EINVAL;
......@@ -445,9 +444,7 @@ int snd_card_disconnect(struct snd_card *card)
#endif
/* notify all devices that we are disconnected */
err = snd_device_disconnect_all(card);
if (err < 0)
dev_err(card->dev, "not all devices for card %i can be disconnected\n", card->number);
snd_device_disconnect_all(card);
snd_info_card_disconnect(card);
if (card->registered) {
......
......@@ -160,7 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep)
input_dev->name = "HDA Digital PCBeep";
input_dev->phys = beep->phys;
input_dev->id.bustype = BUS_PCI;
input_dev->dev.parent = &codec->bus->card->card_dev;
input_dev->dev.parent = &codec->card->card_dev;
input_dev->id.vendor = codec->vendor_id >> 16;
input_dev->id.product = codec->vendor_id & 0xffff;
......@@ -224,7 +224,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
if (beep == NULL)
return -ENOMEM;
snprintf(beep->phys, sizeof(beep->phys),
"card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
"card%d/codec#%d/beep0", codec->card->number, codec->addr);
/* enable linear scale */
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_2, 0x01);
......
......@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/export.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
......@@ -106,16 +107,28 @@ static int hda_codec_driver_probe(struct device *dev)
}
err = codec->preset->patch(codec);
if (err < 0) {
module_put(owner);
goto error;
if (err < 0)
goto error_module;
err = snd_hda_codec_build_pcms(codec);
if (err < 0)
goto error_module;
err = snd_hda_codec_build_controls(codec);
if (err < 0)
goto error_module;
if (codec->card->registered) {
err = snd_card_register(codec->card);
if (err < 0)
goto error_module;
}
return 0;
error_module:
module_put(owner);
error:
codec->preset = NULL;
memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
snd_hda_codec_cleanup_for_unbind(codec);
return err;
}
......@@ -125,12 +138,19 @@ static int hda_codec_driver_remove(struct device *dev)
if (codec->patch_ops.free)
codec->patch_ops.free(codec);
codec->preset = NULL;
memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
snd_hda_codec_cleanup_for_unbind(codec);
module_put(dev->driver->owner);
return 0;
}
static void hda_codec_driver_shutdown(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
codec->patch_ops.reboot_notify(codec);
}
int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
struct module *owner)
{
......@@ -139,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
drv->driver.bus = &snd_hda_bus_type;
drv->driver.probe = hda_codec_driver_probe;
drv->driver.remove = hda_codec_driver_remove;
drv->driver.shutdown = hda_codec_driver_shutdown;
drv->driver.pm = &hda_codec_driver_pm;
return driver_register(&drv->driver);
}
......@@ -287,9 +308,9 @@ int snd_hda_codec_configure(struct hda_codec *codec)
}
/* audio codec should override the mixer name */
if (codec->afg || !*codec->bus->card->mixername)
snprintf(codec->bus->card->mixername,
sizeof(codec->bus->card->mixername),
if (codec->afg || !*codec->card->mixername)
snprintf(codec->card->mixername,
sizeof(codec->card->mixername),
"%s %s", codec->vendor_name, codec->chip_name);
return 0;
......
This diff is collapsed.
......@@ -21,6 +21,7 @@
#ifndef __SOUND_HDA_CODEC_H
#define __SOUND_HDA_CODEC_H
#include <linux/kref.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
......@@ -131,8 +132,6 @@ struct hda_bus {
/* unsolicited event queue */
struct hda_bus_unsolicited unsol;
char workq_name[16];
struct workqueue_struct *workq; /* common workqueue for codecs */
/* assigned PCMs */
DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
......@@ -268,12 +267,17 @@ struct hda_pcm {
int device; /* device number to assign */
struct snd_pcm *pcm; /* assigned PCM instance */
bool own_chmap; /* codec driver provides own channel maps */
/* private: */
struct hda_codec *codec;
struct kref kref;
struct list_head list;
};
/* codec information */
struct hda_codec {
struct device dev;
struct hda_bus *bus;
struct snd_card *card;
unsigned int addr; /* codec addr*/
struct list_head list; /* list point */
......@@ -300,8 +304,7 @@ struct hda_codec {
struct hda_codec_ops patch_ops;
/* PCM to create, set by patch_ops.build_pcms callback */
unsigned int num_pcms;
struct hda_pcm *pcm_info;
struct list_head pcm_list_head;
/* codec specific info */
void *spec;
......@@ -345,6 +348,7 @@ struct hda_codec {
#endif
/* misc flags */
unsigned int in_freeing:1; /* being released */
unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
* status change
* (e.g. Realtek codecs)
......@@ -420,8 +424,8 @@ enum {
* constructors
*/
int snd_hda_bus_new(struct snd_card *card, struct hda_bus **busp);
int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
struct hda_codec **codecp);
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
unsigned int codec_addr, struct hda_codec **codecp);
int snd_hda_codec_configure(struct hda_codec *codec);
int snd_hda_codec_update_widgets(struct hda_codec *codec);
......@@ -510,15 +514,24 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
/*
* Mixer
*/
int snd_hda_build_controls(struct hda_bus *bus);
int snd_hda_codec_build_controls(struct hda_codec *codec);
/*
* PCM
*/
int snd_hda_build_pcms(struct hda_bus *bus);
int snd_hda_codec_parse_pcms(struct hda_codec *codec);
int snd_hda_codec_build_pcms(struct hda_codec *codec);
__printf(2, 3)
struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
const char *fmt, ...);
static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm)
{
kref_get(&pcm->kref);
}
void snd_hda_codec_pcm_put(struct hda_pcm *pcm);
int snd_hda_codec_prepare(struct hda_codec *codec,
struct hda_pcm_stream *hinfo,
unsigned int stream,
......@@ -550,7 +563,6 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
* Misc
*/
void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
void snd_hda_bus_reboot_notify(struct hda_bus *bus);
void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state);
......
......@@ -27,7 +27,6 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <sound/core.h>
#include <sound/initval.h>
#include "hda_controller.h"
......@@ -416,9 +415,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
azx_dev->running = 0;
spin_unlock_irqrestore(&chip->reg_lock, flags);
azx_release_device(azx_dev);
hinfo->ops.close(hinfo, apcm->codec, substream);
if (hinfo->ops.close)
hinfo->ops.close(hinfo, apcm->codec, substream);
snd_hda_power_down(apcm->codec);
mutex_unlock(&chip->open_mutex);
snd_hda_codec_pcm_put(apcm->info);
return 0;
}
......@@ -805,11 +806,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
int err;
int buff_step;
snd_hda_codec_pcm_get(apcm->info);
mutex_lock(&chip->open_mutex);
azx_dev = azx_assign_device(chip, substream);
if (azx_dev == NULL) {
mutex_unlock(&chip->open_mutex);
return -EBUSY;
err = -EBUSY;
goto unlock;
}
runtime->hw = azx_pcm_hw;
runtime->hw.channels_min = hinfo->channels_min;
......@@ -844,12 +846,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
buff_step);
snd_hda_power_up(apcm->codec);
err = hinfo->ops.open(hinfo, apcm->codec, substream);
if (hinfo->ops.open)
err = hinfo->ops.open(hinfo, apcm->codec, substream);
else
err = -ENODEV;
if (err < 0) {
azx_release_device(azx_dev);
snd_hda_power_down(apcm->codec);
mutex_unlock(&chip->open_mutex);
return err;
goto powerdown;
}
snd_pcm_limit_hw_rates(runtime);
/* sanity check */
......@@ -858,10 +861,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_BUG_ON(!runtime->hw.formats) ||
snd_BUG_ON(!runtime->hw.rates)) {
azx_release_device(azx_dev);
hinfo->ops.close(hinfo, apcm->codec, substream);
snd_hda_power_down(apcm->codec);
mutex_unlock(&chip->open_mutex);
return -EINVAL;
if (hinfo->ops.close)
hinfo->ops.close(hinfo, apcm->codec, substream);
err = -EINVAL;
goto powerdown;
}
/* disable LINK_ATIME timestamps for capture streams
......@@ -880,6 +883,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
mutex_unlock(&chip->open_mutex);
return 0;
powerdown:
snd_hda_power_down(apcm->codec);
unlock:
mutex_unlock(&chip->open_mutex);
snd_hda_codec_pcm_put(apcm->info);
return err;
}
static int azx_pcm_mmap(struct snd_pcm_substream *substream,
......@@ -974,14 +984,9 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
*/
static int azx_alloc_cmd_io(struct azx *chip)
{
int err;
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
PAGE_SIZE, &chip->rb);
if (err < 0)
dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n");
return err;
return chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
PAGE_SIZE, &chip->rb);
}
static void azx_init_cmd_io(struct azx *chip)
......@@ -1467,7 +1472,6 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
int azx_alloc_stream_pages(struct azx *chip)
{
int i, err;
struct snd_card *card = chip->card;
for (i = 0; i < chip->num_streams; i++) {
dsp_lock_init(&chip->azx_dev[i]);
......@@ -1475,18 +1479,14 @@ int azx_alloc_stream_pages(struct azx *chip)
err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
BDL_SIZE,
&chip->azx_dev[i].bdl);
if (err < 0) {
dev_err(card->dev, "cannot allocate BDL\n");
if (err < 0)
return -ENOMEM;
}
}
/* allocate memory for the position buffer */
err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
chip->num_streams * 8, &chip->posbuf);
if (err < 0) {
dev_err(card->dev, "cannot allocate posbuf\n");
if (err < 0)
return -ENOMEM;
}
/* allocate CORB/RIRB */
err = azx_alloc_cmd_io(chip);
......@@ -1893,7 +1893,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
for (c = 0; c < max_slots; c++) {
if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
struct hda_codec *codec;
err = snd_hda_codec_new(bus, c, &codec);
err = snd_hda_codec_new(bus, bus->card, c, &codec);
if (err < 0)
continue;
codec->jackpoll_interval = get_jackpoll_interval(chip);
......@@ -1966,30 +1966,5 @@ int azx_init_stream(struct azx *chip)
}
EXPORT_SYMBOL_GPL(azx_init_stream);
/*
* reboot notifier for hang-up problem at power-down
*/
static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
{
struct azx *chip = container_of(nb, struct azx, reboot_notifier);
snd_hda_bus_reboot_notify(chip->bus);
azx_stop_chip(chip);
return NOTIFY_OK;
}
void azx_notifier_register(struct azx *chip)
{
chip->reboot_notifier.notifier_call = azx_halt;
register_reboot_notifier(&chip->reboot_notifier);
}
EXPORT_SYMBOL_GPL(azx_notifier_register);
void azx_notifier_unregister(struct azx *chip)
{
if (chip->reboot_notifier.notifier_call)
unregister_reboot_notifier(&chip->reboot_notifier);
}
EXPORT_SYMBOL_GPL(azx_notifier_unregister);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Common HDA driver functions");
......@@ -362,9 +362,6 @@ struct azx {
/* for debugging */
unsigned int last_cmd[AZX_MAX_CODECS];
/* reboot notifier (for mysterious hangup problem at power-down) */
struct notifier_block reboot_notifier;
#ifdef CONFIG_SND_HDA_DSP_LOADER
struct azx_dev saved_azx_dev;
#endif
......@@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
int azx_codec_configure(struct azx *chip);
int azx_init_stream(struct azx *chip);
void azx_notifier_register(struct azx *chip);
void azx_notifier_unregister(struct azx *chip);
#endif /* __SOUND_HDA_CONTROLLER_H */
......@@ -4675,7 +4675,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
err = snd_hda_create_dig_out_ctls(codec,
spec->multiout.dig_out_nid,
spec->multiout.dig_out_nid,
spec->pcm_rec[1].pcm_type);
spec->pcm_rec[1]->pcm_type);
if (err < 0)
return err;
if (!spec->no_analog) {
......@@ -5146,20 +5146,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
int snd_hda_gen_build_pcms(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;
struct hda_pcm *info;
const struct hda_pcm_stream *p;
bool have_multi_adcs;
codec->num_pcms = 1;
codec->pcm_info = info;
if (spec->no_analog)
goto skip_analog;
fill_pcm_stream_name(spec->stream_name_analog,
sizeof(spec->stream_name_analog),
" Analog", codec->chip_name);
info->name = spec->stream_name_analog;
info = snd_hda_codec_pcm_new(codec, "%s", spec->stream_name_analog);
if (!info)
return -ENOMEM;
spec->pcm_rec[0] = info;
if (spec->multiout.num_dacs > 0) {
p = spec->stream_analog_playback;
......@@ -5192,10 +5192,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
fill_pcm_stream_name(spec->stream_name_digital,
sizeof(spec->stream_name_digital),
" Digital", codec->chip_name);
codec->num_pcms = 2;
info = snd_hda_codec_pcm_new(codec, "%s",
spec->stream_name_digital);
if (!info)
return -ENOMEM;
codec->slave_dig_outs = spec->multiout.slave_dig_outs;
info = spec->pcm_rec + 1;
info->name = spec->stream_name_digital;
spec->pcm_rec[1] = info;
if (spec->dig_out_type)
info->pcm_type = spec->dig_out_type;
else
......@@ -5229,9 +5231,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
fill_pcm_stream_name(spec->stream_name_alt_analog,
sizeof(spec->stream_name_alt_analog),
" Alt Analog", codec->chip_name);
codec->num_pcms = 3;
info = spec->pcm_rec + 2;
info->name = spec->stream_name_alt_analog;
info = snd_hda_codec_pcm_new(codec, "%s",
spec->stream_name_alt_analog);
if (!info)
return -ENOMEM;
spec->pcm_rec[2] = info;
if (spec->alt_dac_nid) {
p = spec->stream_analog_alt_playback;
if (!p)
......
......@@ -144,7 +144,7 @@ struct hda_gen_spec {
int const_channel_count; /* channel count for all */
/* PCM information */
struct hda_pcm pcm_rec[3]; /* used in build_pcms() */
struct hda_pcm *pcm_rec[3]; /* used in build_pcms() */
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
......
......@@ -101,7 +101,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
int err;
sprintf(hwname, "HDA Codec %d", codec->addr);
err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep);
err = snd_hwdep_new(codec->card, hwname, codec->addr, &hwdep);
if (err < 0)
return err;
codec->hwdep = hwdep;
......
......@@ -528,10 +528,10 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
if (ok == 1) {
azx_dev->irq_pending = 0;
return ok;
} else if (ok == 0 && chip->bus && chip->bus->workq) {
} else if (ok == 0) {
/* bogus IRQ, process it later */
azx_dev->irq_pending = 1;
queue_work(chip->bus->workq, &hda->irq_pending_work);
schedule_work(&hda->irq_pending_work);
}
return 0;
}
......@@ -893,8 +893,8 @@ static int azx_runtime_resume(struct device *dev)
if (status && bus) {
list_for_each_entry(codec, &bus->codec_list, list)
if (status & (1 << codec->addr))
queue_delayed_work(codec->bus->workq,
&codec->jackpoll_work, codec->jackpoll_interval);
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
}
/* disable controller Wake Up event*/
......@@ -1066,8 +1066,6 @@ static int azx_free(struct azx *chip)
azx_del_card_list(chip);
azx_notifier_unregister(chip);
hda->init_failed = 1; /* to be sure */
complete_all(&hda->probe_wait);
......@@ -1383,7 +1381,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
hda = kzalloc(sizeof(*hda), GFP_KERNEL);
if (!hda) {
dev_err(card->dev, "Cannot allocate hda\n");
pci_disable_device(pci);
return -ENOMEM;
}
......@@ -1564,10 +1561,8 @@ static int azx_first_init(struct azx *chip)
chip->num_streams = chip->playback_streams + chip->capture_streams;
chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
GFP_KERNEL);
if (!chip->azx_dev) {
dev_err(card->dev, "cannot malloc azx_dev\n");
if (!chip->azx_dev)
return -ENOMEM;
}
err = azx_alloc_stream_pages(chip);
if (err < 0)
......@@ -1898,22 +1893,11 @@ static int azx_probe_continue(struct azx *chip)
goto out_free;
}
/* create PCM streams */
err = snd_hda_build_pcms(chip->bus);
if (err < 0)
goto out_free;
/* create mixer controls */
err = snd_hda_build_controls(chip->bus);
if (err < 0)
goto out_free;
err = snd_card_register(chip->card);
if (err < 0)
goto out_free;
chip->running = 1;
azx_notifier_register(chip);
azx_add_card_list(chip);
snd_hda_set_power_save(chip->bus, power_save * 1000);
if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
......@@ -1934,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci)
snd_card_free(card);
}
static void azx_shutdown(struct pci_dev *pci)
{
struct snd_card *card = pci_get_drvdata(pci);
struct azx *chip;
if (!card)
return;
chip = card->private_data;
if (chip && chip->running)
azx_stop_chip(chip);
}
/* PCI IDs */
static const struct pci_device_id azx_ids[] = {
/* CPT */
......@@ -2156,6 +2152,7 @@ static struct pci_driver azx_driver = {
.id_table = azx_ids,
.probe = azx_probe,
.remove = azx_remove,
.shutdown = azx_shutdown,
.driver = {
.pm = AZX_PM_OPS,
},
......
......@@ -135,7 +135,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
#ifdef CONFIG_SND_HDA_INPUT_JACK
/* free jack instances manually when clearing/reconfiguring */
if (!codec->bus->shutdown && jack->jack)
snd_device_free(codec->bus->card, jack->jack);
snd_device_free(codec->card, jack->jack);
#endif
for (cb = jack->callback; cb; cb = next) {
next = cb->next;
......@@ -340,7 +340,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
if (!jack->kctl || jack->block_report)
continue;
state = get_jack_plug_state(jack->pin_sense);
snd_kctl_jack_report(codec->bus->card, jack->kctl, state);
snd_kctl_jack_report(codec->card, jack->kctl, state);
#ifdef CONFIG_SND_HDA_INPUT_JACK
if (jack->jack)
snd_jack_report(jack->jack,
......@@ -412,11 +412,11 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
jack->phantom_jack = !!phantom_jack;
state = snd_hda_jack_detect(codec, nid);
snd_kctl_jack_report(codec->bus->card, kctl, state);
snd_kctl_jack_report(codec->card, kctl, state);
#ifdef CONFIG_SND_HDA_INPUT_JACK
if (!phantom_jack) {
jack->type = get_input_jack_type(codec, nid);
err = snd_jack_new(codec->bus->card, name, jack->type,
err = snd_jack_new(codec->card, name, jack->type,
&jack->jack);
if (err < 0)
return err;
......
......@@ -150,6 +150,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
__snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
int snd_hda_codec_reset(struct hda_codec *codec);
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
enum {
HDA_VMUTE_OFF,
......
......@@ -99,10 +99,10 @@ static void print_nid_array(struct snd_info_buffer *buffer,
static void print_nid_pcms(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid)
{
int pcm, type;
int type;
struct hda_pcm *cpcm;
for (pcm = 0; pcm < codec->num_pcms; pcm++) {
cpcm = &codec->pcm_info[pcm];
list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
for (type = 0; type < 2; type++) {
if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
continue;
......@@ -861,7 +861,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec)
int err;
snprintf(name, sizeof(name), "codec#%d", codec->addr);
err = snd_card_proc_new(codec->bus->card, name, &entry);
err = snd_card_proc_new(codec->card, name, &entry);
if (err < 0)
return err;
......
......@@ -149,7 +149,7 @@ static int reconfig_codec(struct hda_codec *codec)
err = snd_hda_codec_build_controls(codec);
if (err < 0)
goto error;
err = snd_card_register(codec->bus->card);
err = snd_card_register(codec->card);
error:
snd_hda_power_down(codec);
return err;
......
......@@ -290,8 +290,6 @@ static int hda_tegra_dev_free(struct snd_device *device)
int i;
struct azx *chip = device->device_data;
azx_notifier_unregister(chip);
if (chip->initialized) {
for (i = 0; i < chip->num_streams; i++)
azx_stream_stop(chip, &chip->azx_dev[i]);
......@@ -497,22 +495,11 @@ static int hda_tegra_probe(struct platform_device *pdev)
if (err < 0)
goto out_free;
/* create PCM streams */
err = snd_hda_build_pcms(chip->bus);
if (err < 0)
goto out_free;
/* create mixer controls */
err = snd_hda_build_controls(chip->bus);
if (err < 0)
goto out_free;
err = snd_card_register(chip->card);
if (err < 0)
goto out_free;
chip->running = 1;
azx_notifier_register(chip);
snd_hda_set_power_save(chip->bus, power_save * 1000);
return 0;
......@@ -527,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev)
return snd_card_free(dev_get_drvdata(&pdev->dev));
}
static void hda_tegra_shutdown(struct platform_device *pdev)
{
struct snd_card *card = dev_get_drvdata(&pdev->dev);
struct azx *chip;
if (!card)
return;
chip = card->private_data;
if (chip && chip->running)
azx_stop_chip(chip);
}
static struct platform_driver tegra_platform_hda = {
.driver = {
.name = "tegra-hda",
......@@ -535,6 +534,7 @@ static struct platform_driver tegra_platform_hda = {
},
.probe = hda_tegra_probe,
.remove = hda_tegra_remove,
.shutdown = hda_tegra_shutdown,
};
module_platform_driver(tegra_platform_hda);
......
......@@ -23,7 +23,7 @@ DECLARE_EVENT_CLASS(hda_cmd,
),
TP_fast_assign(
__entry->card = (codec)->bus->card->number;
__entry->card = (codec)->card->number;
__entry->addr = (codec)->addr;
__entry->val = (val);
),
......@@ -71,7 +71,7 @@ DECLARE_EVENT_CLASS(hda_power,
),
TP_fast_assign(
__entry->card = (codec)->bus->card->number;
__entry->card = (codec)->card->number;
__entry->addr = (codec)->addr;
),
......
......@@ -719,7 +719,6 @@ struct ca0132_spec {
unsigned int num_inputs;
hda_nid_t shared_mic_nid;
hda_nid_t shared_out_nid;
struct hda_pcm pcm_rec[5]; /* PCM information */
/* chip access */
struct mutex chipio_mutex; /* chip access mutex */
......@@ -4036,12 +4035,11 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
static int ca0132_build_pcms(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;
struct hda_pcm *info;
codec->pcm_info = info;
codec->num_pcms = 0;
info->name = "CA0132 Analog";
info = snd_hda_codec_pcm_new(codec, "CA0132 Analog");
if (!info)
return -ENOMEM;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
......@@ -4049,27 +4047,27 @@ static int ca0132_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
codec->num_pcms++;
info++;
info->name = "CA0132 Analog Mic-In2";
info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
if (!info)
return -ENOMEM;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
codec->num_pcms++;
info++;
info->name = "CA0132 What U Hear";
info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear");
if (!info)
return -ENOMEM;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2];
codec->num_pcms++;
if (!spec->dig_out && !spec->dig_in)
return 0;
info++;
info->name = "CA0132 Digital";
info = snd_hda_codec_pcm_new(codec, "CA0132 Digital");
if (!info)
return -ENOMEM;
info->pcm_type = HDA_PCM_TYPE_SPDIF;
if (spec->dig_out) {
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
......@@ -4081,7 +4079,6 @@ static int ca0132_build_pcms(struct hda_codec *codec)
ca0132_pcm_digital_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
}
codec->num_pcms++;
return 0;
}
......@@ -4352,7 +4349,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
const struct dsp_image_seg *dsp_os_image;
const struct firmware *fw_entry;
if (request_firmware(&fw_entry, EFX_FILE, codec->bus->card->dev) != 0)
if (request_firmware(&fw_entry, EFX_FILE, codec->card->dev) != 0)
return false;
dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
......@@ -4413,8 +4410,7 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
* state machine run.
*/
cancel_delayed_work_sync(&spec->unsol_hp_work);
queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work,
msecs_to_jiffies(500));
schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
cb->tbl->block_report = 1;
}
......
......@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
bool non_pcm;
bool chmap_set; /* channel-map override by ALSA API? */
unsigned char chmap[8]; /* ALSA API channel-map */
char pcm_name[8]; /* filled in build_pcm callbacks */
#ifdef CONFIG_PROC_FS
struct snd_info_entry *proc_entry;
#endif
......@@ -132,7 +131,7 @@ struct hdmi_spec {
int num_pins;
struct snd_array pins; /* struct hdmi_spec_per_pin */
struct snd_array pcm_rec; /* struct hda_pcm */
struct hda_pcm *pcm_rec[16];
unsigned int channels_max; /* max over all cvts */
struct hdmi_eld temp_eld;
......@@ -355,8 +354,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
#define get_cvt(spec, idx) \
((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
#define get_pcm_rec(spec, idx) \
((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx))
#define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx])
static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)
{
......@@ -579,7 +577,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
int err;
snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
err = snd_card_proc_new(codec->bus->card, name, &entry);
err = snd_card_proc_new(codec->card, name, &entry);
if (err < 0)
return err;
......@@ -594,7 +592,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
static void eld_proc_free(struct hdmi_spec_per_pin *per_pin)
{
if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) {
snd_device_free(per_pin->codec->bus->card, per_pin->proc_entry);
snd_device_free(per_pin->codec->card, per_pin->proc_entry);
per_pin->proc_entry = NULL;
}
}
......@@ -1578,9 +1576,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
update_eld = true;
}
else if (repoll) {
queue_delayed_work(codec->bus->workq,
&per_pin->work,
msecs_to_jiffies(300));
schedule_delayed_work(&per_pin->work,
msecs_to_jiffies(300));
goto unlock;
}
}
......@@ -1624,7 +1621,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
}
if (eld_changed)
snd_ctl_notify(codec->bus->card,
snd_ctl_notify(codec->card,
SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
&per_pin->eld_ctl->id);
unlock:
......@@ -2056,11 +2053,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
struct hdmi_spec_per_pin *per_pin;
per_pin = get_pin(spec, pin_idx);
sprintf(per_pin->pcm_name, "HDMI %d", pin_idx);
info = snd_array_new(&spec->pcm_rec);
info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx);
if (!info)
return -ENOMEM;
info->name = per_pin->pcm_name;
spec->pcm_rec[pin_idx] = info;
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->own_chmap = true;
......@@ -2070,9 +2066,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
/* other pstr fields are set in open */
}
codec->num_pcms = spec->num_pins;
codec->pcm_info = spec->pcm_rec.list;
return 0;
}
......@@ -2125,13 +2118,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
/* add channel maps */
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hda_pcm *pcm;
struct snd_pcm_chmap *chmap;
struct snd_kcontrol *kctl;
int i;
if (!codec->pcm_info[pin_idx].pcm)
pcm = spec->pcm_rec[pin_idx];
if (!pcm || !pcm->pcm)
break;
err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm,
err = snd_pcm_add_chmap_ctls(pcm->pcm,
SNDRV_PCM_STREAM_PLAYBACK,
NULL, 0, pin_idx, &chmap);
if (err < 0)
......@@ -2186,14 +2181,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums)
{
snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums);
snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums);
snd_array_init(&spec->pcm_rec, sizeof(struct hda_pcm), nums);
}
static void hdmi_array_free(struct hdmi_spec *spec)
{
snd_array_free(&spec->pins);
snd_array_free(&spec->cvts);
snd_array_free(&spec->pcm_rec);
}
static void generic_hdmi_free(struct hda_codec *codec)
......@@ -2204,11 +2197,10 @@ static void generic_hdmi_free(struct hda_codec *codec)
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
cancel_delayed_work(&per_pin->work);
cancel_delayed_work_sync(&per_pin->work);
eld_proc_free(per_pin);
}
flush_workqueue(codec->bus->workq);
hdmi_array_free(spec);
kfree(spec);
}
......@@ -2381,11 +2373,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
chans = get_wcaps(codec, per_cvt->cvt_nid);
chans = get_wcaps_channels(chans);
info = snd_array_new(&spec->pcm_rec);
info = snd_hda_codec_pcm_new(codec, "HDMI 0");
if (!info)
return -ENOMEM;
info->name = get_pin(spec, 0)->pcm_name;
sprintf(info->name, "HDMI 0");
spec->pcm_rec[0] = info;
info->pcm_type = HDA_PCM_TYPE_HDMI;
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
*pstr = spec->pcm_playback;
......@@ -2393,9 +2384,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
if (pstr->channels_max <= 2 && chans && chans <= 16)
pstr->channels_max = chans;
codec->num_pcms = 1;
codec->pcm_info = info;
return 0;
}
......
......@@ -5850,7 +5850,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
{
if (action == HDA_FIXUP_ACT_BUILD) {
struct alc_spec *spec = codec->spec;
spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
}
}
......
......@@ -83,7 +83,6 @@
struct si3054_spec {
unsigned international;
struct hda_pcm pcm;
};
......@@ -199,11 +198,11 @@ static const struct hda_pcm_stream si3054_pcm = {
static int si3054_build_pcms(struct hda_codec *codec)
{
struct si3054_spec *spec = codec->spec;
struct hda_pcm *info = &spec->pcm;
codec->num_pcms = 1;
codec->pcm_info = info;
info->name = "Si3054 Modem";
struct hda_pcm *info;
info = snd_hda_codec_pcm_new(codec, "Si3054 Modem");
if (!info)
return -ENOMEM;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg;
......
......@@ -222,8 +222,7 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
if (!spec->hp_work_active) {
codec->jackpoll_interval = msecs_to_jiffies(100);
snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0);
queue_delayed_work(codec->bus->workq,
&codec->jackpoll_work, 0);
schedule_delayed_work(&codec->jackpoll_work, 0);
spec->hp_work_active = true;
}
} else if (!hp_detect_with_aa(codec))
......@@ -683,8 +682,10 @@ static int vt1708_build_pcms(struct hda_codec *codec)
* 24bit samples are used. Until any workaround is found,
* disable the 24bit format, so far.
*/
for (i = 0; i < codec->num_pcms; i++) {
struct hda_pcm *info = &spec->gen.pcm_rec[i];
for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) {
struct hda_pcm *info = spec->gen.pcm_rec[i];
if (!info)
continue;
if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams ||
info->pcm_type != HDA_PCM_TYPE_AUDIO)
continue;
......@@ -907,16 +908,16 @@ static int patch_vt1708S(struct hda_codec *codec)
if (get_codec_type(codec) == VT1708BCE) {
kfree(codec->chip_name);
codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
snprintf(codec->bus->card->mixername,
sizeof(codec->bus->card->mixername),
snprintf(codec->card->mixername,
sizeof(codec->card->mixername),
"%s %s", codec->vendor_name, codec->chip_name);
}
/* correct names for VT1705 */
if (codec->vendor_id == 0x11064397) {
kfree(codec->chip_name);
codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
snprintf(codec->bus->card->mixername,
sizeof(codec->bus->card->mixername),
snprintf(codec->card->mixername,
sizeof(codec->card->mixername),
"%s %s", codec->vendor_name, codec->chip_name);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment