int i2schar_devinit(void) { static bool initialized; struct i2s_dev_s *i2s; int ret; /* Have we already initialized? */ if (!initialized) { /* Call s5j_i2s_initialize() to get an instance of the I2S interface */ i2s = s5j_i2s_initialize(0); if (!i2s) { auddbg("ERROR: Failed to get the S5J I2S driver\n"); return -ENODEV; } /* Register the I2S character driver at "/dev/i2schar0" */ ret = i2schar_register(i2s, CONFIG_S5JT200_I2SCHAR_MINOR); if (ret < 0) { auddbg("ERROR: i2schar_register failed: %d\n", ret); return ret; } I2S_ERR_CB_REG(i2s, err_cb, "Error_Test_String"); /* Now we are initialized */ initialized = true; } return OK; }
static void audio_callback(FAR void *handle, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status) { FAR struct audio_upperhalf_s *upper = (FAR struct audio_upperhalf_s *)handle; audllvdbg("Entry\n"); /* Perform operation based on reason code */ switch (reason) { case AUDIO_CALLBACK_DEQUEUE: { /* Call the dequeue routine */ audio_dequeuebuffer(upper, apb, status); break; } case AUDIO_CALLBACK_IOERR: { } break; default: { auddbg("Unknown callback reason code %d\n", reason); break; } } }
static void audio_callback(FAR void *handle, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status) #endif { FAR struct audio_upperhalf_s *upper = (FAR struct audio_upperhalf_s *)handle; audllvdbg("Entry\n"); /* Perform operation based on reason code */ switch (reason) { case AUDIO_CALLBACK_DEQUEUE: { /* Call the dequeue routine */ #ifdef CONFIG_AUDIO_MULTI_SESSION audio_dequeuebuffer(upper, apb, status, session); #else audio_dequeuebuffer(upper, apb, status); #endif break; } /* Lower-half I/O error occurred */ case AUDIO_CALLBACK_IOERR: { } break; /* Lower-half driver has completed a playback */ case AUDIO_CALLBACK_COMPLETE: { /* Send a complete message to the user if a message queue is registered */ #ifdef CONFIG_AUDIO_MULTI_SESSION audio_complete(upper, apb, status, session); #else audio_complete(upper, apb, status); #endif } break; default: { auddbg("Unknown callback reason code %d\n", reason); break; } } }
void apb_free(FAR struct ap_buffer_s *apb) { int refcount; /* Perform a reference count decrement and possibly release the memory */ apb_semtake(apb); refcount = apb->crefs--; apb_semgive(apb); if (refcount == 1) { auddbg("Freeing %p\n", apb); kufree(apb); } }
int sam_audio_null_initialize(int minor) { FAR struct audio_lowerhalf_s *nullaudio; FAR struct audio_lowerhalf_s *pcm; static bool initialized = false; char devname[12]; int ret; auddbg("minor %d\n", minor); DEBUGASSERT(minor >= 0 && minor <= 25); /* Have we already initialized? Since we never uninitialize we must prevent * multiple initializations. This is necessary, for example, when the * touchscreen example is used as a built-in application in NSH and can be * called numerous time. It will attempt to initialize each time. */ if (!initialized) { /* Get a null audio interface */ nullaudio = audio_null_initialize(); if (!nullaudio) { auddbg("Failed to get the NULL audio interface\n"); ret = -ENODEV; goto errout; } /* No we can embed the null audio interface into a PCM decoder * instance so that we will have a PCM front end for the NULL * audio driver. */ pcm = pcm_decode_initialize(nullaudio); if (!pcm) { auddbg("ERROR: Failed create the PCM decoder\n"); ret = -ENODEV; goto errout_with_nullaudio; } /* Create a device name */ snprintf(devname, 12, "pcm%d", minor); /* Finally, we can register the PCM/NULL audio device. */ ret = audio_register(devname, pcm); if (ret < 0) { auddbg("ERROR: Failed to register /dev/%s device: %d\n", devname, ret); goto errout_with_pcm; } /* Now we are initialized */ initialized = true; } return OK; /* Error exits. Unfortunately there is no mechanism in place now to * recover resources from most errors on initialization failures. */ errout_with_nullaudio: errout_with_pcm: errout: return ret; }
int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev) { FAR struct audio_upperhalf_s *upper; char path[AUDIO_MAX_DEVICE_PATH]; static bool dev_audio_created = false; #ifndef CONFIG_AUDIO_CUSTOM_DEV_PATH const char* devname = "/dev/audio"; #elif !defined(CONFIG_AUDIO_DEV_ROOT) const char* devname = CONFIG_AUDIO_DEV_PATH; const char* ptr; char* pathptr; #endif /* Allocate the upper-half data structure */ upper = (FAR struct audio_upperhalf_s *)kzalloc(sizeof(struct audio_upperhalf_s)); if (!upper) { auddbg("Allocation failed\n"); return -ENOMEM; } /* Initialize the Audio device structure (it was already zeroed by kzalloc()) */ sem_init(&upper->exclsem, 0, 1); upper->dev = dev; #ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH #ifdef CONFIG_AUDIO_DEV_ROOT /* This is the simple case ... No need to make a directory */ strcpy(path, "/dev/"); strcat(path, name); #else /* Ensure the path begins with "/dev" as we don't support placing device * anywhere but in the /dev directory */ DEBUGASSERT(strncmp(devname, "/dev", 4) == 0); /* Create a /dev/audio directory. */ if (!dev_audio_created) { /* Get path name after "/dev" */ ptr = &devname[4]; if (*ptr == '/') { ptr++; } strcpy(path, "/dev/"); pathptr = &path[5]; /* Do mkdir for each segment of the path */ while (*ptr != '\0') { /* Build next path segment into path variable */ while (*ptr != '/' && *ptr != '\0') { *pathptr++ = *ptr++; } *pathptr = '\0'; /* Make this level of directory */ mkdir(path, 0644); /* Check for another level */ *pathptr++ = '/'; if (*ptr == '/') { ptr++; } } /* Indicate we have created the audio dev path */ dev_audio_created = true; } /* Now build the path for registration */ strcpy(path, devname); if (devname[sizeof(devname)-1] != '/') { strcat(path, "/"); } strcat(path, name); #endif /* CONFIG_AUDIO_DEV_PATH=="/dev" */ #else /* CONFIG_AUDIO_CUSTOM_DEV_PATH */ /* Create a /dev/audio directory. */ if (!dev_audio_created) { /* We don't check for error here because even if it fails, then * the register_driver call below will return an error condition * for us. */ mkdir(devname, 0644); dev_audio_created = true; } /* Register the Audio device */ memset(path, 0, AUDIO_MAX_DEVICE_PATH); strcpy(path, devname); strcat(path, "/"); strncat(path, name, AUDIO_MAX_DEVICE_PATH - 11); #endif audvdbg("Registering %s\n", path); return register_driver(path, &g_audioops, 0666, upper); }