28 #include <linux/slab.h>
30 #include <linux/export.h>
44 static unsigned char rate_reg_tables[2][4][9] = {
147 static unsigned char rate_cregs[9] = {
159 static unsigned char get_slot_reg(
struct ac97_pcm *pcm,
unsigned short cidx,
160 unsigned short slot,
int dbl)
169 return rate_reg_tables[dbl][pcm->
r[dbl].rate_table[cidx]][slot - 3];
171 return rate_cregs[slot - 3];
174 static int set_spdif_rate(
struct snd_ac97 *ac97,
unsigned short rate)
185 case 48000: bits = 0;
break;
271 snd_ac97_update_power(ac97, reg, 1);
281 if (rate != 48000 && rate != 96000)
294 return set_spdif_rate(ac97, rate);
300 tmp = (rate * ac97->
bus->clock) / 48000;
322 static unsigned short get_pslots(
struct snd_ac97 *ac97,
unsigned char *
rate_table,
unsigned short *spdif_slots)
324 if (!ac97_is_audio(ac97))
326 if (ac97_is_rev22(ac97) || ac97_can_amap(ac97)) {
327 unsigned short slots = 0;
328 if (ac97_is_rev22(ac97)) {
332 switch (ac97->
addr) {
339 switch (ac97->
addr) {
378 unsigned short slots;
397 static unsigned short get_cslots(
struct snd_ac97 *ac97)
399 unsigned short slots;
401 if (!ac97_is_audio(ac97))
408 static unsigned int get_rates(
struct ac97_pcm *pcm,
unsigned int cidx,
unsigned short slots,
int dbl)
411 unsigned int rates = ~0;
414 for (i = 3; i < 12; i++) {
415 if (!(slots & (1 << i)))
417 reg = get_slot_reg(pcm, cidx, i, dbl);
426 rates &= pcm->
r[dbl].codec[cidx]->rates[
idx];
445 unsigned short pcms_count,
451 unsigned short avail_slots[2][4];
452 unsigned char rate_table[2][4];
454 unsigned short spdif_slots[4];
461 memset(avail_slots, 0,
sizeof(avail_slots));
462 memset(rate_table, 0,
sizeof(rate_table));
463 memset(spdif_slots, 0,
sizeof(spdif_slots));
464 for (i = 0; i < 4; i++) {
468 avail_slots[0][
i] = get_pslots(codec, &rate_table[0][i], &spdif_slots[i]);
469 avail_slots[1][
i] = get_cslots(codec);
471 for (j = 0; j <
i; j++) {
473 avail_slots[1][
i] &= ~avail_slots[1][
j];
478 for (i = 0; i < pcms_count; i++) {
492 slots = pcm->
r[0].slots;
493 for (j = 0; j < 4 &&
slots; j++) {
498 tmp = spdif_slots[
j];
500 tmp = avail_slots[pcm->
stream][
j];
504 for (k = 0; k <
i; k++) {
506 tmp &= ~rpcms[
k].
r[0].rslots[
j];
510 tmp &= pcm->
r[0].slots;
513 rpcm->
r[0].rslots[
j] =
tmp;
514 rpcm->
r[0].codec[
j] = bus->
codec[
j];
515 rpcm->
r[0].rate_table[
j] = rate_table[pcm->
stream][
j];
519 rates = get_rates(rpcm, j, tmp, 0);
521 avail_slots[pcm->
stream][
j] &= ~tmp;
524 rpcm->
r[0].slots |=
tmp;
530 rate_table[pcm->
stream][0] == 0) {
533 if ((tmp & pcm->
r[1].slots) ==
tmp) {
534 rpcm->
r[1].slots =
tmp;
535 rpcm->
r[1].rslots[0] =
tmp;
536 rpcm->
r[1].rate_table[0] = 0;
537 rpcm->
r[1].codec[0] = bus->
codec[0];
539 avail_slots[pcm->
stream][0] &= ~tmp;
543 rates = get_rates(rpcm, 0, tmp, 1);
547 if (rpcm->
rates == ~0)
570 int i, cidx,
r, ok_flag;
571 unsigned int reg_ok[4] = {0,0,0,0};
578 for (cidx = 0; cidx < 4; cidx++)
580 err = set_spdif_rate(bus->
codec[cidx], rate);
585 spin_lock_irq(&pcm->
bus->bus_lock);
586 for (i = 3; i < 12; i++) {
587 if (!(slots & (1 << i)))
590 for (cidx = 0; cidx < 4; cidx++) {
592 spin_unlock_irq(&pcm->
bus->bus_lock);
596 if (pcm->
r[r].rslots[cidx] & (1 << i)) {
602 spin_unlock_irq(&pcm->
bus->bus_lock);
609 spin_unlock_irq(&pcm->
bus->bus_lock);
610 for (i = 3; i < 12; i++) {
611 if (!(slots & (1 << i)))
613 for (cidx = 0; cidx < 4; cidx++) {
614 if (pcm->
r[r].rslots[cidx] & (1 << i)) {
615 reg = get_slot_reg(pcm, cidx, i, r);
625 snd_printk(
KERN_ERR "error in snd_ac97_set_rate: cidx=%d, reg=0x%x, rate=%d, err=%d\n", cidx, reg, rate, err);
651 unsigned short slots = pcm->
aslots;
654 #ifdef CONFIG_SND_AC97_POWER_SAVE
656 for (i = 3; i < 12; i++) {
657 if (!(slots & (1 << i)))
659 for (cidx = 0; cidx < 4; cidx++) {
660 if (pcm->
r[r].rslots[cidx] & (1 << i)) {
661 int reg = get_slot_reg(pcm, cidx, i, r);
662 snd_ac97_update_power(pcm->
r[r].codec[cidx],
670 spin_lock_irq(&pcm->
bus->bus_lock);
671 for (i = 3; i < 12; i++) {
672 if (!(slots & (1 << i)))
674 for (cidx = 0; cidx < 4; cidx++)
679 spin_unlock_irq(&pcm->
bus->bus_lock);
689 if (channels->
min > 2) {
704 if (rate->
min > 48000) {
705 static const struct snd_interval double_rate_channels = {
727 double_rate_hw_constraint_rate,
NULL,
732 double_rate_hw_constraint_channels,
NULL,