25 #define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__
26 #define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt)
30 #include <linux/list.h>
33 #include <linux/poll.h>
34 #include <linux/slab.h>
35 #include <linux/sched.h>
36 #include <linux/uio.h>
38 #include <linux/module.h>
80 int maj = imajor(inode);
97 pr_err(
"no device data!!!\n");
102 pr_err(
"this device doesn't support this direction\n");
113 data->
stream.direction = dirn;
116 runtime = kzalloc(
sizeof(*runtime),
GFP_KERNEL);
124 data->
stream.runtime = runtime;
137 static int snd_compr_free(
struct inode *inode,
struct file *f)
150 if (!stream->
ops->pointer)
152 stream->
ops->pointer(stream, tstamp);
153 pr_debug(
"dsp consumed till %d total %d bytes\n",
164 snd_compr_update_tstamp(stream, &avail->
tstamp);
170 if (stream->
runtime->total_bytes_available == 0 &&
172 pr_debug(
"detected init and someone forgot to do a write\n");
173 return stream->
runtime->buffer_size;
175 pr_debug(
"app wrote %lld, DSP consumed %lld\n",
176 stream->
runtime->total_bytes_available,
177 stream->
runtime->total_bytes_transferred);
178 if (stream->
runtime->total_bytes_available ==
179 stream->
runtime->total_bytes_transferred) {
180 pr_debug(
"both pointers are same, returning full avail\n");
181 return stream->
runtime->buffer_size;
190 avail_calc = stream->
runtime->buffer_size -
192 pr_debug(
"calc avail as %ld, app_ptr %lld, hw+ptr %lld\n", avail_calc,
195 if (avail_calc >= stream->
runtime->buffer_size)
196 avail_calc -= stream->
runtime->buffer_size;
197 pr_debug(
"ret avail as %ld\n", avail_calc);
198 avail->
avail = avail_calc;
206 return snd_compr_calc_avail(stream, &avail);
215 avail = snd_compr_calc_avail(stream, &ioctl_avail);
216 ioctl_avail.avail =
avail;
219 &ioctl_avail,
sizeof(ioctl_avail)))
225 const char __user *
buf,
size_t count)
247 if (stream->
ops->ack)
248 stream->
ops->ack(stream, count);
252 static ssize_t snd_compr_write(
struct file *f,
const char __user *buf,
253 size_t count, loff_t *
offset)
272 avail = snd_compr_get_avail(stream);
273 pr_debug(
"avail returned %ld\n", (
unsigned long)avail);
278 if (stream->
ops->copy)
279 retval = stream->
ops->copy(stream, buf, avail);
281 retval = snd_compr_write_data(stream, buf, avail);
289 pr_debug(
"stream prepared, Houston we are good to go\n");
297 static ssize_t snd_compr_read(
struct file *f,
char __user *buf,
298 size_t count, loff_t *offset)
335 poll_wait(f, &stream->
runtime->sleep, wait);
337 avail = snd_compr_get_avail(stream);
338 pr_debug(
"avail is %ld\n", (
unsigned long)avail);
340 switch (stream->
runtime->state) {
345 retval = snd_compr_get_poll(stream);
351 if (avail >= stream->
runtime->fragment_size)
352 retval = snd_compr_get_poll(stream);
372 if (!stream->
ops->get_caps)
375 retval = stream->
ops->get_caps(stream, &
caps);
385 snd_compr_get_codec_caps(
struct snd_compr_stream *stream,
unsigned long arg)
390 if (!stream->
ops->get_codec_caps)
397 retval = stream->
ops->get_codec_caps(stream, caps);
400 if (
copy_to_user((
void __user *)arg, caps,
sizeof(*caps)))
415 buffer_size = params->
buffer.fragment_size * params->
buffer.fragments;
416 if (stream->
ops->copy) {
426 stream->
runtime->fragment_size = params->
buffer.fragment_size;
429 stream->
runtime->buffer_size = buffer_size;
436 if (params->
buffer.fragment_size == 0 ||
444 if (params->
codec.ch_in == 0 || params->
codec.ch_out == 0)
467 if (
copy_from_user(params, (
void __user *)arg,
sizeof(*params))) {
472 retval = snd_compress_check_input(params);
476 retval = snd_compr_allocate_buffer(stream, params);
482 retval = stream->
ops->set_params(stream, params);
500 if (!stream->
ops->get_params)
506 retval = stream->
ops->get_params(stream, params);
509 if (
copy_to_user((
char __user *)arg, params,
sizeof(*params)))
522 snd_compr_update_tstamp(stream, &tstamp);
524 &tstamp,
sizeof(tstamp)) ? -
EFAULT : 0;
574 stream->
runtime->hw_pointer = 0;
575 stream->
runtime->app_pointer = 0;
576 stream->
runtime->total_bytes_available = 0;
577 stream->
runtime->total_bytes_transferred = 0;
597 static long snd_compr_ioctl(
struct file *f,
unsigned int cmd,
unsigned long arg)
615 retval = snd_compr_get_caps(stream, arg);
618 retval = snd_compr_get_codec_caps(stream, arg);
621 retval = snd_compr_set_params(stream, arg);
624 retval = snd_compr_get_params(stream, arg);
630 retval = snd_compr_ioctl_avail(stream, arg);
633 retval = snd_compr_pause(stream);
636 retval = snd_compr_resume(stream);
639 retval = snd_compr_start(stream);
642 retval = snd_compr_stop(stream);
645 retval = snd_compr_drain(stream);
654 .open = snd_compr_open,
655 .release = snd_compr_free,
656 .write = snd_compr_write,
657 .read = snd_compr_read,
658 .unlocked_ioctl = snd_compr_ioctl,
659 .mmap = snd_compr_mmap,
660 .poll = snd_compr_poll,
674 pr_debug(
"reg %s for device %s, direction %d\n", str, compr->
name,
678 compr->
device, &snd_compr_file_ops, compr, str);
680 pr_err(
"snd_register_device failed\n %d", ret);
687 static int snd_compress_dev_disconnect(
struct snd_device *device)
708 .dev_register = snd_compress_dev_register,
709 .dev_disconnect = snd_compress_dev_disconnect,
719 static int snd_compress_add_device(
struct snd_compr *device)
733 pr_err(
"failed with %d\n", ret);
738 static int snd_compress_remove_device(
struct snd_compr *device)
755 pr_debug(
"Registering compressed device %s\n", device->
name);
769 retval = snd_compress_add_device(device);
777 pr_debug(
"Removing compressed device %s\n", device->
name);
779 snd_compress_remove_device(device);
785 static int __init snd_compress_init(
void)
790 static void __exit snd_compress_exit(
void)