int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc) { struct snd_pcm *sp; struct snd_card *sc = itvsc->sc; struct v4l2_device *v4l2_dev = itvsc->v4l2_dev; struct ivtv *itv = to_ivtv(v4l2_dev); int ret; ret = snd_pcm_new(sc, "CX2341[56] PCM", 0, /* PCM device 0, the only one for this card */ 0, /* 0 playback substreams */ 1, /* 1 capture substream */ &sp); if (ret) { IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n", __func__, ret); goto err_exit; } spin_lock_init(&itvsc->slock); snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE, &snd_ivtv_pcm_capture_ops); sp->info_flags = 0; sp->private_data = itvsc; strlcpy(sp->name, itv->card_name, sizeof(sp->name)); return 0; err_exit: return ret; }
static int ivtv_alsa_load(struct ivtv *itv) { struct v4l2_device *v4l2_dev = &itv->v4l2_dev; struct ivtv_stream *s; if (v4l2_dev == NULL) { pr_err("ivtv-alsa: %s: struct v4l2_device * is NULL\n", __func__); return 0; } itv = to_ivtv(v4l2_dev); if (itv == NULL) { pr_err("ivtv-alsa itv is NULL\n"); return 0; } s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; if (s->vdev.v4l2_dev == NULL) { IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " "skipping\n", __func__); return 0; } if (itv->alsa != NULL) { IVTV_ALSA_ERR("%s: struct snd_ivtv_card * already exists\n", __func__); return 0; } if (snd_ivtv_init(v4l2_dev)) { IVTV_ALSA_ERR("%s: failed to create struct snd_ivtv_card\n", __func__); } else { IVTV_DEBUG_ALSA_INFO("%s: created ivtv ALSA interface instance " "\n", __func__); } return 0; }
static int snd_ivtv_init(struct v4l2_device *v4l2_dev) { struct ivtv *itv = to_ivtv(v4l2_dev); struct snd_card *sc = NULL; struct snd_ivtv_card *itvsc; int ret; /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */ /* (1) Check and increment the device index */ /* This is a no-op for us. We'll use the itv->instance */ /* (2) Create a card instance */ ret = snd_card_new(&itv->pdev->dev, SNDRV_DEFAULT_IDX1, /* use first available id */ SNDRV_DEFAULT_STR1, /* xid from end of shortname*/ THIS_MODULE, 0, &sc); if (ret) { IVTV_ALSA_ERR("%s: snd_card_new() failed with err %d\n", __func__, ret); goto err_exit; } /* (3) Create a main component */ ret = snd_ivtv_card_create(v4l2_dev, sc, &itvsc); if (ret) { IVTV_ALSA_ERR("%s: snd_ivtv_card_create() failed with err %d\n", __func__, ret); goto err_exit_free; } /* (4) Set the driver ID and name strings */ snd_ivtv_card_set_names(itvsc); /* (5) Create other components: mixer, PCM, & proc files */ #if 0 ret = snd_ivtv_mixer_create(itvsc); if (ret) { IVTV_ALSA_WARN("%s: snd_ivtv_mixer_create() failed with err %d:" " proceeding anyway\n", __func__, ret); } #endif ret = snd_ivtv_pcm_create(itvsc); if (ret) { IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n", __func__, ret); goto err_exit_free; } /* FIXME - proc files */ /* (7) Set the driver data and return 0 */ /* We do this out of normal order for PCI drivers to avoid races */ itv->alsa = itvsc; /* (6) Register the card instance */ ret = snd_card_register(sc); if (ret) { itv->alsa = NULL; IVTV_ALSA_ERR("%s: snd_card_register() failed with err %d\n", __func__, ret); goto err_exit_free; } return 0; err_exit_free: if (sc != NULL) snd_card_free(sc); kfree(itvsc); err_exit: return ret; }