[alsa-devel] [PATCH] [RFC 8/13] Intel SST sound card driver
Harsha, Priya
priya.harsha at intel.com
Mon Aug 3 09:15:08 CEST 2009
I tried but still finding the same issue...the probe function and the related functions are as follows... please let me know if you see any issues
___________
/* Driver Init/exit functionalities */
/**
* snd_intelmad_pcm- to setup pcm for the card
* @card: pointer to the sound card structure
*@intelmaddata: pointer to internal context
* This function is called from probe function to set up pcm params and functions
*/
static int __devinit snd_intelmad_pcm(struct snd_card *card,
struct snd_intelmad *intelmaddata)
{
struct snd_pcm *pcm;
int i, ret_val = 0;
char name[32] = INTEL_MAD;
WARN_ON(!card);
WARN_ON(!intelmaddata);
for (i = 0; i < MAX_DEVICES; i++) {
ret_val = snd_pcm_new(card, name, i, PLAYBACK_COUNT,
CAPTURE_COUNT, &pcm);
if (0 != ret_val)
break;
/* setup the ops for playback and capture streams */
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
&snd_intelmad_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&snd_intelmad_capture_ops);
/* setup private data which can be retrieved when required */
pcm->private_data = intelmaddata;
pcm->info_flags = 0;
strncpy(pcm->name, card->shortname, strlen(card->shortname));
/* allocate dma pages for ALSA stream operations */
snd_pcm_lib_preallocate_pages_for_all(pcm,
SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL),
MIN_BUFFER, MAX_BUFFER);
}
return ret_val;
}
/**
* snd_intelmad_mixer- to setup mixer settings of the card
*@intelmaddata: pointer to internal context
* This function is called from probe function to set up mixer controls
*/
static int __devinit snd_intelmad_mixer(struct snd_intelmad *intelmaddata)
{
struct snd_card *card = NULL;
unsigned int idx;
int ret_val = 0;
char *mixername = "IntelMAD Controls";
WARN_ON(!intelmaddata);
card = intelmaddata->card;
strncpy(card->mixername, mixername, strlen(mixername));
/* add all widget controls and expose the same */
for (idx = 0; idx < ARRAY_SIZE(snd_intelmad_controls); idx++) {
ret_val = snd_ctl_add(card,
snd_ctl_new1(&snd_intelmad_controls[idx],
intelmaddata));
sst_dbg("mixer[idx]=%d added \n", idx);
if (ret_val) {
sst_err("adding of control failed index = %d\n", idx);
break;
}
}
return ret_val;
}
static int __devinit snd_intelmad_register_irq(
struct snd_intelmad *intelmaddata)
{
int ret_val = 0;
u32 regbase = AUDINT_BASE, regsize = 8;
/* interpret irq field */
sst_dbg("irq = 0x%x\n", intelmaddata->irq);
if ((intelmaddata->irq) & PMIC_SOUND_IRQ_TYPE_MASK) {
/* irq -> GPE_ID */
intelmaddata->irq = intelmaddata->irq &
(~PMIC_SOUND_IRQ_TYPE_MASK);
sst_dbg("gpe = 0x%x\n", intelmaddata->irq);
ret_val = request_gpe(intelmaddata->irq,
(gpio_function_t)snd_intelmad_intr_handler,
intelmaddata, 0);
if (ret_val) {
sst_dbg("cannot register gpe\n");
return ret_val;
}
} else {
/* irq -> system irq */
ret_val = request_irq(intelmaddata->irq,
snd_intelmad_intr_handler,
IRQF_SHARED, DRIVER_NAME,
intelmaddata);
if (ret_val) {
sst_dbg("cannot register IRQ\n");
return ret_val;
}
}
intelmaddata->int_base = ioremap_nocache(regbase, regsize);
return ret_val;
}
static int __devinit snd_intelmad_sst_register(
struct snd_intelmad *intelmaddata)
{
int ret_val;
struct sc_reg_access pmic_reg = {0,};
pmic_reg.reg_addr = 0;
ret_val = sst_sc_reg_access(&pmic_reg, PMIC_READ, 1);
if (ret_val)
return ret_val;
vendor_id = pmic_reg.value & (MASK2|MASK1|MASK0);
sst_info("orginal reg n extrated vendor id = 0x%x %d\n",
pmic_reg.value, vendor_id);
if (vendor_id < 0 || vendor_id > 2) {
sst_err("vendor card not supported!!\n");
return -EIO;
}
intelmaddata->sstdrv_ops->module_name = SST_CARD_NAMES;
intelmaddata->sstdrv_ops->vendor_id = vendor_id;
intelmaddata->sstdrv_ops->scard_ops = &v[vendor_id];
/* registering with SST driver to get access to SST APIs to use */
ret_val = register_sst_card(intelmaddata->sstdrv_ops);
if (ret_val) {
sst_err("sst card registration failed\n");
return ret_val;
}
vendor_id = intelmaddata->sstdrv_ops->vendor_id;
intelmaddata->pmic_status = PMIC_UNINIT;
return ret_val;
}
/**
* snd_intelmad_create- called from probe to create a snd device
*@intelmaddata : pointer to the internal context
*@card : pointer to the sound card
* This function is called when driver module is started
*/
static int __devinit snd_intelmad_create(
struct snd_intelmad *intelmaddata,
struct snd_card *card)
{
int ret_val;
static struct snd_device_ops ops = {
.dev_free = snd_intelmad_dev_free,
};
WARN_ON(!intelmaddata);
WARN_ON(!card);
/* ALSA api to register for the device */
ret_val = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelmaddata, &ops);
return ret_val;
}
/**
* snd_intelmad_jack- to setup jack settings of the card
*@intelmaddata: pointer to internal context
* This function is called from probe function to set up mixer controls
*/
static int __devinit snd_intelmad_jack(struct snd_intelmad *intelmaddata)
{
struct snd_jack *jack;
int retval;
jack = &intelmaddata->jack[0];
retval = snd_jack_new(intelmaddata->card, "Headphone",
SND_JACK_HEADPHONE, &jack);
if (retval < 0)
return retval;
jack->private_data = jack;
snd_jack_report(jack, jack->type);
jack = &intelmaddata->jack[1];
retval = snd_jack_new(intelmaddata->card, "Headset",
SND_JACK_HEADSET, &jack);
if (retval < 0)
return retval;
jack->private_data = jack;
snd_jack_report(jack, jack->type);
return retval;
}
/**
* snd_intelmad_probe- function registred for init
*@spi : pointer to the spi device context
* This function is called when the device is initialized
*/
int __devinit snd_intelmad_probe(struct spi_device *spi)
{
struct snd_card *card;
int ret_val = 0;
struct snd_intelmad *intelmaddata;
sst_dbg("called \n");
/* allocate memory for saving internal context and working */
intelmaddata = kzalloc(sizeof(*intelmaddata), GFP_KERNEL);
if (NULL == intelmaddata)
return -ENOMEM;
/* allocate memory for LPE API set */
intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops),
GFP_KERNEL);
if (!intelmaddata->sstdrv_ops) {
sst_err("mem alloctn fail \n");
kfree(intelmaddata);
return -ENOMEM;
}
/* create a card instance with ALSA framework */
ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card);
if (ret_val) {
sst_err("snd_card_create fail \n");
goto free_allocs;
}
intelmaddata->spi = spi;
intelmaddata->irq = spi->irq;
dev_set_drvdata(&spi->dev, intelmaddata);
intelmaddata->card = card;
intelmaddata->card_id = card_id;
intelmaddata->card_index = card_index;
strncpy(card->driver, INTEL_MAD, strlen(INTEL_MAD));
strncpy(card->shortname, INTEL_MAD, strlen(INTEL_MAD));
ret_val = snd_intelmad_pcm(card, intelmaddata);
if (ret_val) {
sst_err("snd_intelmad_pcm failed\n");
goto free_allocs;
}
ret_val = snd_intelmad_mixer(intelmaddata);
if (ret_val) {
sst_err("snd_intelmad_mixer failed\n");
goto free_allocs;
}
ret_val = snd_intelmad_jack(intelmaddata);
if (ret_val) {
sst_err("snd_intelmad_jack failed\n");
goto free_allocs;
}
#ifdef REG_IRQ
ret_val = snd_intelmad_register_irq(intelmaddata);
if (ret_val) {
sst_err("snd_intelmad_register_irq fail\n");
goto free_allocs;
}
/*ret_val = snd_intelmad_register_netlink();
if (ret_val) {
sst_dbg("...complete\n");
return ret_val;
}*/
#endif
/* internal function call to register device with ALSA */
ret_val = snd_intelmad_create(intelmaddata, card);
if (ret_val) {
sst_err("snd_intelmad_create failed\n");
goto free_allocs;
}
card->private_data = &intelmaddata;
snd_card_set_dev(card, &spi->dev);
ret_val = snd_card_register(card);
if (ret_val)
goto free_allocs;
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) {
ret_val = intelmaddata->sstdrv_ops->scard_ops->init_card();
intelmaddata->pmic_status = PMIC_INIT;
sst_dbg("...complete\n");
return ret_val;
}
sst_err("registering with LPE failed \n");
free_allocs:
/* TODO: unregister IRQ */
sst_err("probe failed\n");
/* snd_card_free(card); */
kfree(intelmaddata->sstdrv_ops);
kfree(intelmaddata);
return ret_val;
}
Thanks,
Harsha.
>-----Original Message-----
>From: Mark Brown [mailto:broonie at sirena.org.uk]
>Sent: Saturday, August 01, 2009 3:16 PM
>To: Harsha, Priya
>Cc: alsa-devel at alsa-project.org
>Subject: Re: [alsa-devel] [PATCH] [RFC 8/13] Intel SST sound card driver
>
>On Sat, Aug 01, 2009 at 08:45:31AM +0530, Harsha, Priya wrote:
>> In my probe function, after adding the controls, I added the following
>code
>>
>> retval = snd_jack_new(intelmaddata->card, "Headphone",
>> SND_JACK_HEADPHONE, &jack);
>
>> But I do not see any jacks in /dev/input.... Am I missing anything?
>
>It's hard to say without seeing the whole driver but you do need to
>create the jack before you instantiate the sound card - it will be
>created along with all the other controls and PCMs.
More information about the Alsa-devel
mailing list