/* * AD1843 bitfield definitions. All are named as in the AD1843 data * sheet, with ad1843_ prepended and individual bit numbers removed. * * E.g., bits LSS0 through LSS2 become ad1843_LSS. * * Only the bitfields we need are defined.
*/
/* read the current value of an AD1843 bitfield. */
staticint ad1843_read_bits(struct snd_ad1843 *ad1843, conststruct ad1843_bitfield *field)
{ int w;
w = ad1843->read(ad1843->chip, field->reg); return w >> field->lo_bit & ((1 << field->nbits) - 1);
}
/* * write a new value to an AD1843 bitfield and return the old value.
*/
staticint ad1843_write_bits(struct snd_ad1843 *ad1843, conststruct ad1843_bitfield *field, int newval)
{ int w, mask, oldval, newbits;
w = ad1843->read(ad1843->chip, field->reg);
mask = ((1 << field->nbits) - 1) << field->lo_bit;
oldval = (w & mask) >> field->lo_bit;
newbits = (newval << field->lo_bit) & mask;
w = (w & ~mask) | newbits;
ad1843->write(ad1843->chip, field->reg, w);
return oldval;
}
/* * ad1843_read_multi reads multiple bitfields from the same AD1843 * register. It uses a single read cycle to do it. (Reading the * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20 * microseconds.) * * Called like this. * * ad1843_read_multi(ad1843, nfields, * &ad1843_FIELD1, &val1, * &ad1843_FIELD2, &val2, ...);
*/
staticvoid ad1843_read_multi(struct snd_ad1843 *ad1843, int argcount, ...)
{
va_list ap; conststruct ad1843_bitfield *fp; int w = 0, mask, *value, reg = -1;
va_start(ap, argcount); while (--argcount >= 0) {
fp = va_arg(ap, conststruct ad1843_bitfield *);
value = va_arg(ap, int *); if (reg == -1) {
reg = fp->reg;
w = ad1843->read(ad1843->chip, reg);
}
/* * ad1843_write_multi stores multiple bitfields into the same AD1843 * register. It uses one read and one write cycle to do it. * * Called like this. * * ad1843_write_multi(ad1843, nfields, * &ad1843_FIELD1, val1, * &ad1843_FIELF2, val2, ...);
*/
staticvoid ad1843_write_multi(struct snd_ad1843 *ad1843, int argcount, ...)
{
va_list ap; int reg; conststruct ad1843_bitfield *fp; int value; int w, m, mask, bits;
mask = 0;
bits = 0;
reg = -1;
va_start(ap, argcount); while (--argcount >= 0) {
fp = va_arg(ap, conststruct ad1843_bitfield *);
value = va_arg(ap, int); if (reg == -1)
reg = fp->reg; else
WARN_ON(reg != fp->reg);
m = ((1 << fp->nbits) - 1) << fp->lo_bit;
mask |= m;
bits |= (value << fp->lo_bit) & m;
}
va_end(ap);
if (~mask & 0xFFFF)
w = ad1843->read(ad1843->chip, reg); else
w = 0;
w = (w & ~mask) | bits;
ad1843->write(ad1843->chip, reg, w);
}
int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id)
{ conststruct ad1843_gain *gp = ad1843_gain[id]; int ret;
ret = (1 << gp->lfield->nbits); if (!gp->lmute)
ret -= 1; return ret;
}
/* * ad1843_get_gain reads the specified register and extracts the gain value * using the supplied gain type.
*/
int ad1843_get_gain(struct snd_ad1843 *ad1843, int id)
{ int lg, rg, lm, rm; conststruct ad1843_gain *gp = ad1843_gain[id]; unsignedshort mask = (1 << gp->lfield->nbits) - 1;
ad1843_read_multi(ad1843, 2, gp->lfield, &lg, gp->rfield, &rg); if (gp->negative) {
lg = mask - lg;
rg = mask - rg;
} if (gp->lmute) {
ad1843_read_multi(ad1843, 2, gp->lmute, &lm, gp->rmute, &rm); if (lm)
lg = 0; if (rm)
rg = 0;
} return lg << 0 | rg << 8;
}
/* * Set an audio channel's gain. * * Returns the new gain, which may be lower than the old gain.
*/
int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval)
{ conststruct ad1843_gain *gp = ad1843_gain[id]; unsignedshort mask = (1 << gp->lfield->nbits) - 1;
int lg = (newval >> 0) & mask; int rg = (newval >> 8) & mask; int lm = (lg == 0) ? 1 : 0; int rm = (rg == 0) ? 1 : 0;
void ad1843_shutdown_adc(struct snd_ad1843 *ad1843)
{ /* nothing to do */
}
/* * Fully initialize the ad1843. As described in the AD1843 data * sheet, section "START-UP SEQUENCE". The numbered comments are * subsection headings from the data sheet. See the data sheet, pages * 52-54, for more info. *
* return 0 on success, -errno on failure. */
int ad1843_init(struct snd_ad1843 *ad1843)
{ unsignedlong later;
/* Set default recording source to Line In and set * mic gain to +20 dB.
*/
ad1843_set_recsrc(ad1843, 2);
ad1843_write_multi(ad1843, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
/* Set Speaker Out level to +/- 4V and unmute it. */
ad1843_write_multi(ad1843, 3,
&ad1843_HPOS, 1,
&ad1843_HPOM, 0,
&ad1843_MPOM, 0);
return 0;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.