Exemplo n.º 1
0
static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct pcm *pcm = file->private_data;
	struct adsp_open_command rpc;
	int rc = 0;

	if (cmd == AUDIO_GET_STATS) {
		struct msm_audio_stats stats;
		memset(&stats, 0, sizeof(stats));
		if (copy_to_user((void *) arg, &stats, sizeof(stats)))
			return -EFAULT;
		return 0;
	}

	mutex_lock(&pcm->lock);
	switch (cmd) {
	case AUDIO_START:
		memset(&rpc, 0, sizeof(rpc));
		rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE;
		rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK;
		rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT;
		rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_PCM;
		rpc.format_block.standard.channels = pcm->cfg.channel_count;
		rpc.format_block.standard.bits_per_sample = 16;
		rpc.format_block.standard.sampling_rate = pcm->cfg.sample_rate;
		rpc.format_block.standard.is_signed = 1;
		rpc.format_block.standard.is_interleaved = 1;
		rpc.buf_max_size = BUFSZ;
		q6audio_start(pcm->ac, (void *) &rpc, sizeof(rpc));
		break;
	case AUDIO_STOP:
		break;
	case AUDIO_FLUSH:
		break;
	case AUDIO_SET_CONFIG:
		if (copy_from_user(&pcm->cfg, (void *) arg,
				 sizeof(struct msm_audio_config))) {
			rc = -EFAULT;
			break;
		}
		if (pcm->cfg.channel_count < 1 || pcm->cfg.channel_count > 2) {
			rc = -EINVAL;
			break;
		}

		break;
	case AUDIO_GET_CONFIG:
		if (copy_to_user((void *) arg, &pcm->cfg,
				 sizeof(struct msm_audio_config))) {
			rc = -EFAULT;
		}
		break;

	default:
		rc = -EINVAL;
	}

	mutex_unlock(&pcm->lock);
	return rc;
}
Exemplo n.º 2
0
static long q6_evrc_in_ioctl(struct file *file, unsigned int cmd,
                             unsigned long arg)
{
    struct evrc *evrc = file->private_data;
    struct adsp_open_command rpc;
    int rc = 0;

    if (cmd == AUDIO_GET_STATS) {
        struct msm_audio_stats stats;
        memset(&stats, 0, sizeof(stats));
        if (copy_to_user((void *) arg, &stats, sizeof(stats)))
            return -EFAULT;
        return 0;
    }

    mutex_lock(&evrc->lock);
    switch (cmd) {
    case AUDIO_START:
        if (evrc->audio_client) {
            rc = -EBUSY;
            break;
        } else {
            evrc->audio_client = q6audio_open(AUDIO_FLAG_READ,
                                              evrc->str_cfg.buffer_size);

            if (!evrc->audio_client) {
                kfree(evrc);
                rc = -ENOMEM;
                break;
            }
        }

        tx_clk_freq = 8000;

        memset(&rpc, 0, sizeof(rpc));

        rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_EVRC_FS;
        rpc.format_block.standard.channels = 1;
        rpc.format_block.standard.bits_per_sample = 16;
        rpc.format_block.standard.sampling_rate = 8000;
        rpc.format_block.standard.is_signed = 1;
        rpc.format_block.standard.is_interleaved = 0;

        rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ;
        rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT;
        rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD;
        rpc.buf_max_size = evrc->str_cfg.buffer_size;
        rpc.config.evrc.min_rate = evrc->cfg.min_bit_rate;
        rpc.config.evrc.max_rate = evrc->cfg.max_bit_rate;

        q6audio_start(evrc->audio_client, &rpc, sizeof(rpc));
        break;
    case AUDIO_STOP:
        break;
    case AUDIO_FLUSH:
        break;
    case AUDIO_SET_VOLUME:
        break;
    case AUDIO_GET_STREAM_CONFIG:
        if (copy_to_user((void *)arg, &evrc->str_cfg,
                         sizeof(struct msm_audio_stream_config)))
            rc = -EFAULT;
        break;
    case AUDIO_SET_STREAM_CONFIG:
        if (copy_from_user(&evrc->str_cfg, (void *)arg,
                           sizeof(struct msm_audio_stream_config))) {
            rc = -EFAULT;
            break;
        }

        if (evrc->str_cfg.buffer_size < 23) {
            pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__,
                   __func__);
            rc = -EINVAL;
            break;
        }

        if (evrc->str_cfg.buffer_count != 2)
            pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__,
                    __func__);
        break;
    case AUDIO_SET_EVRC_ENC_CONFIG:
        if (copy_from_user(&evrc->cfg, (void *) arg,
                           sizeof(struct msm_audio_evrc_enc_config)))
            rc = -EFAULT;

        if (evrc->cfg.min_bit_rate > 4 || evrc->cfg.min_bit_rate < 1) {
            pr_err("[%s:%s] invalid min bitrate\n", __MM_FILE__,
                   __func__);
            rc = -EINVAL;
        }
        if (evrc->cfg.max_bit_rate > 4 || evrc->cfg.max_bit_rate < 1) {
            pr_err("[%s:%s] invalid max bitrate\n", __MM_FILE__,
                   __func__);
            rc = -EINVAL;
        }
        break;
    case AUDIO_GET_EVRC_ENC_CONFIG:
        if (copy_to_user((void *) arg, &evrc->cfg,
                         sizeof(struct msm_audio_evrc_enc_config)))
            rc = -EFAULT;
        break;

    default:
        rc = -EINVAL;
    }

    mutex_unlock(&evrc->lock);
    return rc;
}