root/sound/pci/emu10k1/io.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_emu10k1_ptr_read
  2. snd_emu10k1_ptr_write
  3. snd_emu10k1_ptr20_read
  4. snd_emu10k1_ptr20_write
  5. snd_emu10k1_spi_write
  6. snd_emu10k1_i2c_write
  7. snd_emu1010_fpga_write
  8. snd_emu1010_fpga_read
  9. snd_emu1010_fpga_link_dst_src_write
  10. snd_emu10k1_intr_enable
  11. snd_emu10k1_intr_disable
  12. snd_emu10k1_voice_intr_enable
  13. snd_emu10k1_voice_intr_disable
  14. snd_emu10k1_voice_intr_ack
  15. snd_emu10k1_voice_half_loop_intr_enable
  16. snd_emu10k1_voice_half_loop_intr_disable
  17. snd_emu10k1_voice_half_loop_intr_ack
  18. snd_emu10k1_voice_set_loop_stop
  19. snd_emu10k1_voice_clear_loop_stop
  20. snd_emu10k1_wait
  21. snd_emu10k1_ac97_read
  22. snd_emu10k1_ac97_write
  23. snd_emu10k1_rate_to_pitch

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4  *                   Creative Labs, Inc.
   5  *  Routines for control of EMU10K1 chips
   6  *
   7  *  BUGS:
   8  *    --
   9  *
  10  *  TODO:
  11  *    --
  12  */
  13 
  14 #include <linux/time.h>
  15 #include <sound/core.h>
  16 #include <sound/emu10k1.h>
  17 #include <linux/delay.h>
  18 #include <linux/export.h>
  19 #include "p17v.h"
  20 
  21 unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
  22 {
  23         unsigned long flags;
  24         unsigned int regptr, val;
  25         unsigned int mask;
  26 
  27         mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
  28         regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
  29 
  30         if (reg & 0xff000000) {
  31                 unsigned char size, offset;
  32                 
  33                 size = (reg >> 24) & 0x3f;
  34                 offset = (reg >> 16) & 0x1f;
  35                 mask = ((1 << size) - 1) << offset;
  36                 
  37                 spin_lock_irqsave(&emu->emu_lock, flags);
  38                 outl(regptr, emu->port + PTR);
  39                 val = inl(emu->port + DATA);
  40                 spin_unlock_irqrestore(&emu->emu_lock, flags);
  41                 
  42                 return (val & mask) >> offset;
  43         } else {
  44                 spin_lock_irqsave(&emu->emu_lock, flags);
  45                 outl(regptr, emu->port + PTR);
  46                 val = inl(emu->port + DATA);
  47                 spin_unlock_irqrestore(&emu->emu_lock, flags);
  48                 return val;
  49         }
  50 }
  51 
  52 EXPORT_SYMBOL(snd_emu10k1_ptr_read);
  53 
  54 void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
  55 {
  56         unsigned int regptr;
  57         unsigned long flags;
  58         unsigned int mask;
  59 
  60         if (snd_BUG_ON(!emu))
  61                 return;
  62         mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
  63         regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
  64 
  65         if (reg & 0xff000000) {
  66                 unsigned char size, offset;
  67 
  68                 size = (reg >> 24) & 0x3f;
  69                 offset = (reg >> 16) & 0x1f;
  70                 mask = ((1 << size) - 1) << offset;
  71                 data = (data << offset) & mask;
  72 
  73                 spin_lock_irqsave(&emu->emu_lock, flags);
  74                 outl(regptr, emu->port + PTR);
  75                 data |= inl(emu->port + DATA) & ~mask;
  76                 outl(data, emu->port + DATA);
  77                 spin_unlock_irqrestore(&emu->emu_lock, flags);          
  78         } else {
  79                 spin_lock_irqsave(&emu->emu_lock, flags);
  80                 outl(regptr, emu->port + PTR);
  81                 outl(data, emu->port + DATA);
  82                 spin_unlock_irqrestore(&emu->emu_lock, flags);
  83         }
  84 }
  85 
  86 EXPORT_SYMBOL(snd_emu10k1_ptr_write);
  87 
  88 unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, 
  89                                           unsigned int reg, 
  90                                           unsigned int chn)
  91 {
  92         unsigned long flags;
  93         unsigned int regptr, val;
  94   
  95         regptr = (reg << 16) | chn;
  96 
  97         spin_lock_irqsave(&emu->emu_lock, flags);
  98         outl(regptr, emu->port + 0x20 + PTR);
  99         val = inl(emu->port + 0x20 + DATA);
 100         spin_unlock_irqrestore(&emu->emu_lock, flags);
 101         return val;
 102 }
 103 
 104 void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, 
 105                                    unsigned int reg, 
 106                                    unsigned int chn, 
 107                                    unsigned int data)
 108 {
 109         unsigned int regptr;
 110         unsigned long flags;
 111 
 112         regptr = (reg << 16) | chn;
 113 
 114         spin_lock_irqsave(&emu->emu_lock, flags);
 115         outl(regptr, emu->port + 0x20 + PTR);
 116         outl(data, emu->port + 0x20 + DATA);
 117         spin_unlock_irqrestore(&emu->emu_lock, flags);
 118 }
 119 
 120 int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
 121                                    unsigned int data)
 122 {
 123         unsigned int reset, set;
 124         unsigned int reg, tmp;
 125         int n, result;
 126         int err = 0;
 127 
 128         /* This function is not re-entrant, so protect against it. */
 129         spin_lock(&emu->spi_lock);
 130         if (emu->card_capabilities->ca0108_chip)
 131                 reg = 0x3c; /* PTR20, reg 0x3c */
 132         else {
 133                 /* For other chip types the SPI register
 134                  * is currently unknown. */
 135                 err = 1;
 136                 goto spi_write_exit;
 137         }
 138         if (data > 0xffff) {
 139                 /* Only 16bit values allowed */
 140                 err = 1;
 141                 goto spi_write_exit;
 142         }
 143 
 144         tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
 145         reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
 146         set = reset | 0x10000; /* Set xxx1xxxx */
 147         snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
 148         tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
 149         snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
 150         result = 1;
 151         /* Wait for status bit to return to 0 */
 152         for (n = 0; n < 100; n++) {
 153                 udelay(10);
 154                 tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
 155                 if (!(tmp & 0x10000)) {
 156                         result = 0;
 157                         break;
 158                 }
 159         }
 160         if (result) {
 161                 /* Timed out */
 162                 err = 1;
 163                 goto spi_write_exit;
 164         }
 165         snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
 166         tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
 167         err = 0;
 168 spi_write_exit:
 169         spin_unlock(&emu->spi_lock);
 170         return err;
 171 }
 172 
 173 /* The ADC does not support i2c read, so only write is implemented */
 174 int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
 175                                 u32 reg,
 176                                 u32 value)
 177 {
 178         u32 tmp;
 179         int timeout = 0;
 180         int status;
 181         int retry;
 182         int err = 0;
 183 
 184         if ((reg > 0x7f) || (value > 0x1ff)) {
 185                 dev_err(emu->card->dev, "i2c_write: invalid values.\n");
 186                 return -EINVAL;
 187         }
 188 
 189         /* This function is not re-entrant, so protect against it. */
 190         spin_lock(&emu->i2c_lock);
 191 
 192         tmp = reg << 25 | value << 16;
 193 
 194         /* This controls the I2C connected to the WM8775 ADC Codec */
 195         snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
 196         tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
 197 
 198         for (retry = 0; retry < 10; retry++) {
 199                 /* Send the data to i2c */
 200                 tmp = 0;
 201                 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
 202                 snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
 203 
 204                 /* Wait till the transaction ends */
 205                 while (1) {
 206                         mdelay(1);
 207                         status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
 208                         timeout++;
 209                         if ((status & I2C_A_ADC_START) == 0)
 210                                 break;
 211 
 212                         if (timeout > 1000) {
 213                                 dev_warn(emu->card->dev,
 214                                            "emu10k1:I2C:timeout status=0x%x\n",
 215                                            status);
 216                                 break;
 217                         }
 218                 }
 219                 //Read back and see if the transaction is successful
 220                 if ((status & I2C_A_ADC_ABORT) == 0)
 221                         break;
 222         }
 223 
 224         if (retry == 10) {
 225                 dev_err(emu->card->dev, "Writing to ADC failed!\n");
 226                 dev_err(emu->card->dev, "status=0x%x, reg=%d, value=%d\n",
 227                         status, reg, value);
 228                 /* dump_stack(); */
 229                 err = -EINVAL;
 230         }
 231     
 232         spin_unlock(&emu->i2c_lock);
 233         return err;
 234 }
 235 
 236 int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
 237 {
 238         unsigned long flags;
 239 
 240         if (reg > 0x3f)
 241                 return 1;
 242         reg += 0x40; /* 0x40 upwards are registers. */
 243         if (value > 0x3f) /* 0 to 0x3f are values */
 244                 return 1;
 245         spin_lock_irqsave(&emu->emu_lock, flags);
 246         outl(reg, emu->port + A_IOCFG);
 247         udelay(10);
 248         outl(reg | 0x80, emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
 249         udelay(10);
 250         outl(value, emu->port + A_IOCFG);
 251         udelay(10);
 252         outl(value | 0x80 , emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
 253         spin_unlock_irqrestore(&emu->emu_lock, flags);
 254 
 255         return 0;
 256 }
 257 
 258 int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value)
 259 {
 260         unsigned long flags;
 261         if (reg > 0x3f)
 262                 return 1;
 263         reg += 0x40; /* 0x40 upwards are registers. */
 264         spin_lock_irqsave(&emu->emu_lock, flags);
 265         outl(reg, emu->port + A_IOCFG);
 266         udelay(10);
 267         outl(reg | 0x80, emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
 268         udelay(10);
 269         *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
 270         spin_unlock_irqrestore(&emu->emu_lock, flags);
 271 
 272         return 0;
 273 }
 274 
 275 /* Each Destination has one and only one Source,
 276  * but one Source can feed any number of Destinations simultaneously.
 277  */
 278 int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src)
 279 {
 280         snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
 281         snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
 282         snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
 283         snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
 284 
 285         return 0;
 286 }
 287 
 288 void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
 289 {
 290         unsigned long flags;
 291         unsigned int enable;
 292 
 293         spin_lock_irqsave(&emu->emu_lock, flags);
 294         enable = inl(emu->port + INTE) | intrenb;
 295         outl(enable, emu->port + INTE);
 296         spin_unlock_irqrestore(&emu->emu_lock, flags);
 297 }
 298 
 299 void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
 300 {
 301         unsigned long flags;
 302         unsigned int enable;
 303 
 304         spin_lock_irqsave(&emu->emu_lock, flags);
 305         enable = inl(emu->port + INTE) & ~intrenb;
 306         outl(enable, emu->port + INTE);
 307         spin_unlock_irqrestore(&emu->emu_lock, flags);
 308 }
 309 
 310 void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
 311 {
 312         unsigned long flags;
 313         unsigned int val;
 314 
 315         spin_lock_irqsave(&emu->emu_lock, flags);
 316         /* voice interrupt */
 317         if (voicenum >= 32) {
 318                 outl(CLIEH << 16, emu->port + PTR);
 319                 val = inl(emu->port + DATA);
 320                 val |= 1 << (voicenum - 32);
 321         } else {
 322                 outl(CLIEL << 16, emu->port + PTR);
 323                 val = inl(emu->port + DATA);
 324                 val |= 1 << voicenum;
 325         }
 326         outl(val, emu->port + DATA);
 327         spin_unlock_irqrestore(&emu->emu_lock, flags);
 328 }
 329 
 330 void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
 331 {
 332         unsigned long flags;
 333         unsigned int val;
 334 
 335         spin_lock_irqsave(&emu->emu_lock, flags);
 336         /* voice interrupt */
 337         if (voicenum >= 32) {
 338                 outl(CLIEH << 16, emu->port + PTR);
 339                 val = inl(emu->port + DATA);
 340                 val &= ~(1 << (voicenum - 32));
 341         } else {
 342                 outl(CLIEL << 16, emu->port + PTR);
 343                 val = inl(emu->port + DATA);
 344                 val &= ~(1 << voicenum);
 345         }
 346         outl(val, emu->port + DATA);
 347         spin_unlock_irqrestore(&emu->emu_lock, flags);
 348 }
 349 
 350 void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
 351 {
 352         unsigned long flags;
 353 
 354         spin_lock_irqsave(&emu->emu_lock, flags);
 355         /* voice interrupt */
 356         if (voicenum >= 32) {
 357                 outl(CLIPH << 16, emu->port + PTR);
 358                 voicenum = 1 << (voicenum - 32);
 359         } else {
 360                 outl(CLIPL << 16, emu->port + PTR);
 361                 voicenum = 1 << voicenum;
 362         }
 363         outl(voicenum, emu->port + DATA);
 364         spin_unlock_irqrestore(&emu->emu_lock, flags);
 365 }
 366 
 367 void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
 368 {
 369         unsigned long flags;
 370         unsigned int val;
 371 
 372         spin_lock_irqsave(&emu->emu_lock, flags);
 373         /* voice interrupt */
 374         if (voicenum >= 32) {
 375                 outl(HLIEH << 16, emu->port + PTR);
 376                 val = inl(emu->port + DATA);
 377                 val |= 1 << (voicenum - 32);
 378         } else {
 379                 outl(HLIEL << 16, emu->port + PTR);
 380                 val = inl(emu->port + DATA);
 381                 val |= 1 << voicenum;
 382         }
 383         outl(val, emu->port + DATA);
 384         spin_unlock_irqrestore(&emu->emu_lock, flags);
 385 }
 386 
 387 void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
 388 {
 389         unsigned long flags;
 390         unsigned int val;
 391 
 392         spin_lock_irqsave(&emu->emu_lock, flags);
 393         /* voice interrupt */
 394         if (voicenum >= 32) {
 395                 outl(HLIEH << 16, emu->port + PTR);
 396                 val = inl(emu->port + DATA);
 397                 val &= ~(1 << (voicenum - 32));
 398         } else {
 399                 outl(HLIEL << 16, emu->port + PTR);
 400                 val = inl(emu->port + DATA);
 401                 val &= ~(1 << voicenum);
 402         }
 403         outl(val, emu->port + DATA);
 404         spin_unlock_irqrestore(&emu->emu_lock, flags);
 405 }
 406 
 407 void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
 408 {
 409         unsigned long flags;
 410 
 411         spin_lock_irqsave(&emu->emu_lock, flags);
 412         /* voice interrupt */
 413         if (voicenum >= 32) {
 414                 outl(HLIPH << 16, emu->port + PTR);
 415                 voicenum = 1 << (voicenum - 32);
 416         } else {
 417                 outl(HLIPL << 16, emu->port + PTR);
 418                 voicenum = 1 << voicenum;
 419         }
 420         outl(voicenum, emu->port + DATA);
 421         spin_unlock_irqrestore(&emu->emu_lock, flags);
 422 }
 423 
 424 void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
 425 {
 426         unsigned long flags;
 427         unsigned int sol;
 428 
 429         spin_lock_irqsave(&emu->emu_lock, flags);
 430         /* voice interrupt */
 431         if (voicenum >= 32) {
 432                 outl(SOLEH << 16, emu->port + PTR);
 433                 sol = inl(emu->port + DATA);
 434                 sol |= 1 << (voicenum - 32);
 435         } else {
 436                 outl(SOLEL << 16, emu->port + PTR);
 437                 sol = inl(emu->port + DATA);
 438                 sol |= 1 << voicenum;
 439         }
 440         outl(sol, emu->port + DATA);
 441         spin_unlock_irqrestore(&emu->emu_lock, flags);
 442 }
 443 
 444 void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
 445 {
 446         unsigned long flags;
 447         unsigned int sol;
 448 
 449         spin_lock_irqsave(&emu->emu_lock, flags);
 450         /* voice interrupt */
 451         if (voicenum >= 32) {
 452                 outl(SOLEH << 16, emu->port + PTR);
 453                 sol = inl(emu->port + DATA);
 454                 sol &= ~(1 << (voicenum - 32));
 455         } else {
 456                 outl(SOLEL << 16, emu->port + PTR);
 457                 sol = inl(emu->port + DATA);
 458                 sol &= ~(1 << voicenum);
 459         }
 460         outl(sol, emu->port + DATA);
 461         spin_unlock_irqrestore(&emu->emu_lock, flags);
 462 }
 463 
 464 void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
 465 {
 466         volatile unsigned count;
 467         unsigned int newtime = 0, curtime;
 468 
 469         curtime = inl(emu->port + WC) >> 6;
 470         while (wait-- > 0) {
 471                 count = 0;
 472                 while (count++ < 16384) {
 473                         newtime = inl(emu->port + WC) >> 6;
 474                         if (newtime != curtime)
 475                                 break;
 476                 }
 477                 if (count > 16384)
 478                         break;
 479                 curtime = newtime;
 480         }
 481 }
 482 
 483 unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 484 {
 485         struct snd_emu10k1 *emu = ac97->private_data;
 486         unsigned long flags;
 487         unsigned short val;
 488 
 489         spin_lock_irqsave(&emu->emu_lock, flags);
 490         outb(reg, emu->port + AC97ADDRESS);
 491         val = inw(emu->port + AC97DATA);
 492         spin_unlock_irqrestore(&emu->emu_lock, flags);
 493         return val;
 494 }
 495 
 496 void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
 497 {
 498         struct snd_emu10k1 *emu = ac97->private_data;
 499         unsigned long flags;
 500 
 501         spin_lock_irqsave(&emu->emu_lock, flags);
 502         outb(reg, emu->port + AC97ADDRESS);
 503         outw(data, emu->port + AC97DATA);
 504         spin_unlock_irqrestore(&emu->emu_lock, flags);
 505 }
 506 
 507 /*
 508  *  convert rate to pitch
 509  */
 510 
 511 unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
 512 {
 513         static u32 logMagTable[128] = {
 514                 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
 515                 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
 516                 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
 517                 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
 518                 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
 519                 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
 520                 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
 521                 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
 522                 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
 523                 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
 524                 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
 525                 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
 526                 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
 527                 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
 528                 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
 529                 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
 530         };
 531         static char logSlopeTable[128] = {
 532                 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
 533                 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
 534                 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
 535                 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
 536                 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
 537                 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
 538                 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
 539                 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
 540                 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
 541                 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
 542                 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
 543                 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
 544                 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
 545                 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
 546                 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
 547                 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
 548         };
 549         int i;
 550 
 551         if (rate == 0)
 552                 return 0;       /* Bail out if no leading "1" */
 553         rate *= 11185;          /* Scale 48000 to 0x20002380 */
 554         for (i = 31; i > 0; i--) {
 555                 if (rate & 0x80000000) {        /* Detect leading "1" */
 556                         return (((unsigned int) (i - 15) << 20) +
 557                                logMagTable[0x7f & (rate >> 24)] +
 558                                         (0x7f & (rate >> 17)) *
 559                                         logSlopeTable[0x7f & (rate >> 24)]);
 560                 }
 561                 rate <<= 1;
 562         }
 563 
 564         return 0;               /* Should never reach this point */
 565 }
 566 

/* [<][>][^][v][top][bottom][index][help] */