static int sst_platform_close(struct snd_pcm_substream *substream) { struct sst_runtime_stream *stream; int ret_val = 0, str_id; pr_debug("sst_platform_close called\n"); stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (str_id) ret_val = stream->sstdrv_ops->pcm_control->close(str_id); unregister_sst_card(stream->sstdrv_ops); kfree(stream->sstdrv_ops); kfree(stream); return ret_val; }
static int snd_intelmad_dev_free(struct snd_device *device) { struct snd_intelmad *intelmaddata; WARN_ON(!device); intelmaddata = device->device_data; pr_debug("snd_intelmad_dev_free called\n"); unregister_sst_card(intelmaddata->sstdrv_ops); /* free allocated memory for internal context */ destroy_workqueue(intelmaddata->mad_jack_wq); device->device_data = NULL; kfree(intelmaddata->sstdrv_ops); kfree(intelmaddata); return 0; }
/** * snd_intelmad_probe- function registred for init * @pdev : pointer to the device struture * This function is called when the device is initialized */ int __devinit snd_intelmad_probe(struct platform_device *pdev) { struct snd_card *card; int ret_val; struct snd_intelmad *intelmaddata; const struct platform_device_id *id = platform_get_device_id(pdev); struct snd_intelmad_probe_info *info = (void *)id->driver_data; pr_debug("probe for %s cpu_id %d\n", pdev->name, info->cpu_id); pr_debug("rq_chache %x of size %x\n", info->irq_cache, info->size); if (!strcmp(pdev->name, DRIVER_NAME_MRST)) pr_debug("detected MRST\n"); else if (!strcmp(pdev->name, DRIVER_NAME_MFLD)) pr_debug("detected MFLD\n"); else { pr_err("detected unknown device abort!!\n"); return -EIO; } if ((info->cpu_id < CPU_CHIP_LINCROFT) || (info->cpu_id > CPU_CHIP_PENWELL)) { pr_err("detected unknown cpu_id abort!!\n"); return -EIO; } /* allocate memory for saving internal context and working */ intelmaddata = kzalloc(sizeof(*intelmaddata), GFP_KERNEL); if (!intelmaddata) { pr_debug("mem alloctn fail\n"); return -ENOMEM; } intelmad_drv = intelmaddata; /* allocate memory for LPE API set */ intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops), GFP_KERNEL); if (!intelmaddata->sstdrv_ops) { pr_err("mem allocation for ops fail\n"); kfree(intelmaddata); return -ENOMEM; } intelmaddata->cpu_id = info->cpu_id; /* create a card instance with ALSA framework */ ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card); if (ret_val) { pr_err("snd_card_create fail\n"); goto free_allocs; } intelmaddata->pdev = pdev; intelmaddata->irq = platform_get_irq(pdev, 0); platform_set_drvdata(pdev, intelmaddata); intelmaddata->card = card; intelmaddata->card_id = card_id; intelmaddata->card_index = card_index; intelmaddata->master_mute = UNMUTE; intelmaddata->playback_cnt = intelmaddata->capture_cnt = 0; strncpy(card->driver, INTEL_MAD, strlen(INTEL_MAD)); strncpy(card->shortname, INTEL_MAD, strlen(INTEL_MAD)); intelmaddata->sstdrv_ops->module_name = SST_CARD_NAMES; /* registering with LPE driver to get access to SST APIs to use */ ret_val = snd_intelmad_sst_register(intelmaddata); if (ret_val) { pr_err("snd_intelmad_sst_register failed\n"); goto set_null_data; } intelmaddata->pmic_status = PMIC_INIT; ret_val = snd_intelmad_pcm(card, intelmaddata); if (ret_val) { pr_err("snd_intelmad_pcm failed\n"); goto free_sst; } ret_val = snd_intelmad_mixer(intelmaddata); if (ret_val) { pr_err("snd_intelmad_mixer failed\n"); goto free_card; } ret_val = snd_intelmad_jack(intelmaddata); if (ret_val) { pr_err("snd_intelmad_jack failed\n"); goto free_card; } intelmaddata->adc_address = mid_initialize_adc(); /*create work queue for jack interrupt*/ INIT_WORK(&intelmaddata->mad_jack_msg.wq, sst_process_mad_jack_detection); intelmaddata->mad_jack_wq = create_workqueue("sst_mad_jack_wq"); if (!intelmaddata->mad_jack_wq) goto free_card; ret_val = snd_intelmad_register_irq(intelmaddata, info->irq_cache, info->size); if (ret_val) { pr_err("snd_intelmad_register_irq fail\n"); goto free_mad_jack_wq; } /* internal function call to register device with ALSA */ ret_val = snd_intelmad_create(intelmaddata, card); if (ret_val) { pr_err("snd_intelmad_create failed\n"); goto set_pvt_data; } card->private_data = &intelmaddata; snd_card_set_dev(card, &pdev->dev); ret_val = snd_card_register(card); if (ret_val) { pr_err("snd_card_register failed\n"); goto set_pvt_data; } if (pdev->dev.platform_data) { int gpio_amp = *(int *)pdev->dev.platform_data; if (gpio_request_one(gpio_amp, GPIOF_OUT_INIT_LOW, "amp power")) gpio_amp = 0; intelmaddata->sstdrv_ops->scard_ops->gpio_amp = gpio_amp; } pr_debug("snd_intelmad_probe complete\n"); return ret_val; set_pvt_data: card->private_data = NULL; free_mad_jack_wq: destroy_workqueue(intelmaddata->mad_jack_wq); free_card: snd_card_free(intelmaddata->card); free_sst: unregister_sst_card(intelmaddata->sstdrv_ops); set_null_data: platform_set_drvdata(pdev, NULL); free_allocs: pr_err("probe failed\n"); snd_card_free(card); kfree(intelmaddata->sstdrv_ops); kfree(intelmaddata); return ret_val; }