aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2016-02-08 08:54:19 -0500
committerTakashi Iwai <tiwai@suse.de>2016-02-09 06:22:10 -0500
commit6f688268b3f4ba494bdf1f9755a3dfa4d91369f0 (patch)
treea4fb786891078da051a246f993e95f876d91d995 /sound/firewire
parentc30076568d20bd6f7a4e021b19672a6b03266430 (diff)
ALSA: dice: purge generating channel cache
Dice interface design doesn't allow drivers to read supported combination between sampling transfer frequencies and the number of Multi bit linear audio data channels. Due to the design, ALSA dice driver changes current sampling transfer frequency to generate cache of the combinations at device probing processing. Although, this idea is worse because ALSA dice driver changes the state of clock. This is not what users want when they save favorite configuration to the device in advance. Furthermore, there's a possibility that the format of data block is decided not only according to current sampling transfer frequency, but also the other factors, i.e. data format for digital interface. It's not good to generate channel cache according to the sampling transfer frequency only. This commit purges processing cache data and related structure members. As a result, users must set preferable sampling transfer frequency before using ALSA PCM applications, as long as they want to start any PCM substreams at the rate except for current one. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/dice/dice-stream.c24
-rw-r--r--sound/firewire/dice/dice.c67
-rw-r--r--sound/firewire/dice/dice.h7
3 files changed, 5 insertions, 93 deletions
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 4f74e3ef58fd..716db092d7c7 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -24,23 +24,6 @@ const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
24 [6] = 192000, 24 [6] = 192000,
25}; 25};
26 26
27int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
28 unsigned int *mode)
29{
30 int i;
31
32 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
33 if (!(dice->clock_caps & BIT(i)))
34 continue;
35 if (snd_dice_rates[i] != rate)
36 continue;
37
38 *mode = (i - 1) / 2;
39 return 0;
40 }
41 return -EINVAL;
42}
43
44static void release_resources(struct snd_dice *dice, 27static void release_resources(struct snd_dice *dice,
45 struct fw_iso_resources *resources) 28 struct fw_iso_resources *resources)
46{ 29{
@@ -100,13 +83,10 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
100{ 83{
101 struct fw_iso_resources *resources; 84 struct fw_iso_resources *resources;
102 __be32 reg[2]; 85 __be32 reg[2];
103 unsigned int i, mode, pcm_chs, midi_ports; 86 unsigned int i, pcm_chs, midi_ports;
104 bool double_pcm_frames; 87 bool double_pcm_frames;
105 int err; 88 int err;
106 89
107 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
108 if (err < 0)
109 goto end;
110 if (stream == &dice->tx_stream) { 90 if (stream == &dice->tx_stream) {
111 resources = &dice->tx_resources; 91 resources = &dice->tx_resources;
112 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO, 92 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
@@ -133,7 +113,7 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
133 * For this quirk, blocking mode is required and PCM buffer size should 113 * For this quirk, blocking mode is required and PCM buffer size should
134 * be aligned to SYT_INTERVAL. 114 * be aligned to SYT_INTERVAL.
135 */ 115 */
136 double_pcm_frames = mode > 1; 116 double_pcm_frames = rate > 96000;
137 if (double_pcm_frames) { 117 if (double_pcm_frames) {
138 rate /= 2; 118 rate /= 2;
139 pcm_chs *= 2; 119 pcm_chs *= 2;
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index b91b3739c810..f7303a650ac2 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -57,65 +57,10 @@ static int check_dice_category(struct fw_unit *unit)
57 return 0; 57 return 0;
58} 58}
59 59
60static int highest_supported_mode_rate(struct snd_dice *dice, 60static int check_clock_caps(struct snd_dice *dice)
61 unsigned int mode, unsigned int *rate)
62{
63 unsigned int i, m;
64
65 for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) {
66 *rate = snd_dice_rates[i - 1];
67 if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0)
68 continue;
69 if (mode == m)
70 break;
71 }
72 if (i == 0)
73 return -EINVAL;
74
75 return 0;
76}
77
78static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode)
79{
80 __be32 values[2];
81 unsigned int rate;
82 int err;
83
84 if (highest_supported_mode_rate(dice, mode, &rate) < 0) {
85 dice->tx_channels[mode] = 0;
86 dice->tx_midi_ports[mode] = 0;
87 dice->rx_channels[mode] = 0;
88 dice->rx_midi_ports[mode] = 0;
89 return 0;
90 }
91
92 err = snd_dice_transaction_set_rate(dice, rate);
93 if (err < 0)
94 return err;
95
96 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
97 values, sizeof(values));
98 if (err < 0)
99 return err;
100
101 dice->tx_channels[mode] = be32_to_cpu(values[0]);
102 dice->tx_midi_ports[mode] = be32_to_cpu(values[1]);
103
104 err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
105 values, sizeof(values));
106 if (err < 0)
107 return err;
108
109 dice->rx_channels[mode] = be32_to_cpu(values[0]);
110 dice->rx_midi_ports[mode] = be32_to_cpu(values[1]);
111
112 return 0;
113}
114
115static int dice_read_params(struct snd_dice *dice)
116{ 61{
117 __be32 value; 62 __be32 value;
118 int mode, err; 63 int err;
119 64
120 /* some very old firmwares don't tell about their clock support */ 65 /* some very old firmwares don't tell about their clock support */
121 if (dice->clock_caps > 0) { 66 if (dice->clock_caps > 0) {
@@ -133,12 +78,6 @@ static int dice_read_params(struct snd_dice *dice)
133 CLOCK_CAP_SOURCE_INTERNAL; 78 CLOCK_CAP_SOURCE_INTERNAL;
134 } 79 }
135 80
136 for (mode = 2; mode >= 0; --mode) {
137 err = dice_read_mode_params(dice, mode);
138 if (err < 0)
139 return err;
140 }
141
142 return 0; 81 return 0;
143} 82}
144 83
@@ -215,7 +154,7 @@ static void do_registration(struct work_struct *work)
215 if (err < 0) 154 if (err < 0)
216 goto error; 155 goto error;
217 156
218 err = dice_read_params(dice); 157 err = check_clock_caps(dice);
219 if (err < 0) 158 if (err < 0)
220 goto error; 159 goto error;
221 160
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 3d5ebebe61ea..c968f9887af6 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -56,10 +56,6 @@ struct snd_dice {
56 unsigned int rsrv_offset; 56 unsigned int rsrv_offset;
57 57
58 unsigned int clock_caps; 58 unsigned int clock_caps;
59 unsigned int tx_channels[3];
60 unsigned int rx_channels[3];
61 unsigned int tx_midi_ports[3];
62 unsigned int rx_midi_ports[3];
63 59
64 struct fw_address_handler notification_handler; 60 struct fw_address_handler notification_handler;
65 int owner_generation; 61 int owner_generation;
@@ -169,9 +165,6 @@ void snd_dice_transaction_destroy(struct snd_dice *dice);
169#define SND_DICE_RATES_COUNT 7 165#define SND_DICE_RATES_COUNT 7
170extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT]; 166extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
171 167
172int snd_dice_stream_get_rate_mode(struct snd_dice *dice,
173 unsigned int rate, unsigned int *mode);
174
175int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate); 168int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate);
176void snd_dice_stream_stop_duplex(struct snd_dice *dice); 169void snd_dice_stream_stop_duplex(struct snd_dice *dice);
177int snd_dice_stream_init_duplex(struct snd_dice *dice); 170int snd_dice_stream_init_duplex(struct snd_dice *dice);