11 #include <linux/slab.h>
14 #include <linux/pci.h>
15 #include <linux/module.h>
16 #include "../soundbus.h"
19 static inline void get_pcm_info(
struct i2sbus_dev *i2sdev,
int in,
26 *other = &i2sdev->out;
41 if (i2s_sf_sclkdiv(mclk / sclk, out))
65 #define CHECK_RATE(rate) \
66 do { if (rates & SNDRV_PCM_RATE_ ##rate) { \
68 if (clock_and_divisors(sysclock_factor, \
69 bus_factor, rate, &dummy)) \
70 rates &= ~SNDRV_PCM_RATE_ ##rate; \
73 static int i2sbus_pcm_open(
struct i2sbus_dev *i2sdev,
int in)
77 int masks_inited = 0,
err;
81 unsigned int rates = 0;
84 int bus_factor = 0, sysclock_factor = 0;
89 get_pcm_info(i2sdev, in, &pi, &other);
92 sdev = &i2sdev->
sound;
103 bus_factor = cii->
codec->bus_factor;
104 sysclock_factor = cii->
codec->sysclock_factor;
108 && cii->
codec->usable(cii, ti, &v)) {
121 if (!masks_inited || !bus_factor || !sysclock_factor) {
203 if (cii->
codec->open) {
211 if (found_this && rev->
codec->close) {
212 rev->
codec->close(rev,
230 static int i2sbus_pcm_close(
struct i2sbus_dev *i2sdev,
int in)
238 get_pcm_info(i2sdev, in, &pi,
NULL);
241 if (cii->
codec->close) {
254 static void i2sbus_wait_for_stop(
struct i2sbus_dev *i2sdev,
263 init_completion(&
done);
265 spin_unlock_irqrestore(&i2sdev->
low_lock, flags);
283 spin_unlock_irqrestore(&i2sdev->
low_lock, flags);
291 get_pcm_info(i2sdev, 0, &pi,
NULL);
292 i2sbus_wait_for_stop(i2sdev, pi);
293 get_pcm_info(i2sdev, 1, &pi,
NULL);
294 i2sbus_wait_for_stop(i2sdev, pi);
309 get_pcm_info(i2sdev, in, &pi,
NULL);
311 i2sbus_wait_for_stop(i2sdev, pi);
318 return i2sbus_hw_free(substream, 0);
323 return i2sbus_hw_free(substream, 1);
326 static int i2sbus_pcm_prepare(
struct i2sbus_dev *i2sdev,
int in)
333 int i, periodsize, nperiods;
343 unsigned int cmd, stopaddr;
347 get_pcm_info(i2sdev, in, &pi, &other);
354 i2sbus_wait_for_stop(i2sdev, pi);
365 || (i2sdev->
rate != runtime->
rate))) {
373 periodsize = snd_pcm_lib_period_bytes(pi->
substream);
374 nperiods = pi->
substream->runtime->periods;
379 memset(command, 0, (nperiods + 2) *
sizeof(
struct dbdma_cmd));
394 cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET |
INTR_ALWAYS;
396 (nperiods + 1) *
sizeof(
struct dbdma_cmd);
397 for (i = 0; i < nperiods; i++, command++, offset += periodsize) {
405 command->command =
cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
413 switch (runtime->
format) {
421 bi.bus_factor = cii->
codec->bus_factor;
424 if (!
bi.bus_factor) {
443 bi.sysclock_factor = cii->
codec->sysclock_factor;
447 if (clock_and_divisors(
bi.sysclock_factor,
454 switch (
bi.bus_factor) {
467 if (cii->
codec->prepare)
508 !(
in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
534 i2sbus_pcm_prepare(i2sdev, 0);
535 i2sbus_pcm_prepare(i2sdev, 1);
539 static int i2sbus_pcm_trigger(
struct i2sbus_dev *i2sdev,
int in,
int cmd)
548 get_pcm_info(i2sdev, in, &pi,
NULL);
616 spin_unlock_irqrestore(&i2sdev->low_lock, flags);
625 get_pcm_info(i2sdev, in, &pi,
NULL);
627 fc =
in_le32(&i2sdev->intfregs->frame_count);
630 if (fc >= pi->
substream->runtime->buffer_size)
631 fc %= pi->
substream->runtime->buffer_size;
645 get_pcm_info(i2sdev, in, &pi,
NULL);
681 if (!(status &
ACTIVE) && (!in || (status & 0x80)))
683 if (--timeout <= 0) {
685 "waiting for DMA to stop!\n");
728 i2sdev->out.substream = substream;
729 return i2sbus_pcm_open(i2sdev, 0);
739 if (i2sdev->out.substream != substream)
741 err = i2sbus_pcm_close(i2sdev, 0);
743 i2sdev->out.substream =
NULL;
753 if (i2sdev->out.substream != substream)
755 return i2sbus_pcm_prepare(i2sdev, 0);
764 if (i2sdev->out.substream != substream)
766 return i2sbus_pcm_trigger(i2sdev, 0, cmd);
776 if (i2sdev->out.substream != substream)
778 return i2sbus_pcm_pointer(i2sdev, 0);
782 .open = i2sbus_playback_open,
783 .close = i2sbus_playback_close,
785 .hw_params = i2sbus_hw_params,
786 .hw_free = i2sbus_playback_hw_free,
787 .prepare = i2sbus_playback_prepare,
788 .trigger = i2sbus_playback_trigger,
789 .pointer = i2sbus_playback_pointer,
798 i2sdev->
in.substream = substream;
799 return i2sbus_pcm_open(i2sdev, 1);
809 if (i2sdev->
in.substream != substream)
811 err = i2sbus_pcm_close(i2sdev, 1);
813 i2sdev->
in.substream =
NULL;
823 if (i2sdev->
in.substream != substream)
825 return i2sbus_pcm_prepare(i2sdev, 1);
834 if (i2sdev->
in.substream != substream)
836 return i2sbus_pcm_trigger(i2sdev, 1, cmd);
846 if (i2sdev->
in.substream != substream)
848 return i2sbus_pcm_pointer(i2sdev, 1);
852 .open = i2sbus_record_open,
853 .close = i2sbus_record_close,
855 .hw_params = i2sbus_hw_params,
856 .hw_free = i2sbus_record_hw_free,
857 .prepare = i2sbus_record_prepare,
858 .trigger = i2sbus_record_trigger,
859 .pointer = i2sbus_record_pointer,
862 static void i2sbus_private_free(
struct snd_pcm *pcm)
868 i2sdev->out.created = 0;
869 i2sdev->
in.created = 0;
873 module_put(p->
codec->owner);
884 int err, in = 0, out = 0;
914 "cannot yet handle multiple different sysclocks!\n");
919 "cannot yet handle multiple different bus clocks!\n");
946 "i2sbus: failed to get soundbus dev reference\n");
957 if (!try_module_get(ci->
owner)) {
959 "i2sbus: failed to get module reference to codec owner!\n");
961 goto out_put_this_module;
969 goto out_put_ci_module;
978 if (!i2sdev->out.created && out) {
979 if (dev->
pcm->card != card) {
982 "Can't attach same bus to different cards!\n");
984 goto out_put_ci_module;
988 goto out_put_ci_module;
990 &i2sbus_playback_ops);
991 i2sdev->out.created = 1;
994 if (!i2sdev->
in.created && in) {
995 if (dev->
pcm->card != card) {
997 "Can't attach same bus to different cards!\n");
999 goto out_put_ci_module;
1003 goto out_put_ci_module;
1005 &i2sbus_record_ops);
1006 i2sdev->
in.created = 1;
1018 goto out_put_ci_module;
1023 dev->
pcm->private_data = i2sdev;
1024 dev->
pcm->private_free = i2sbus_private_free;
1030 64 * 1024, 64 * 1024);
1034 module_put(ci->
owner);
1035 out_put_this_module:
1049 if (i->codec_data == data) {
1056 module_put(cii->
codec->owner);