Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45432371 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (42 commits)
  Staging: usbip: fix build warning on 64bit kernels
  Staging: me4000: remove some compiler warnings
  Staging: wbusb: fix a bunch of compiler warnings
  Staging: w35und: module init cleanup
  Staging: w35und: use gotos for error handling
  Staging: w35und: remove spinlock wrappers
  Staging: sxg: fix compiler warnings.
  Staging: sxg: fix up unused function warnings
  Staging: sxg: clean up C99 comments
  Staging: Lindent the echo driver
  Staging: SLICOSS: Free multicast list at driver exit
  Staging: PCC-ACPI: Fix all checkpatch errors
  Staging: pcc-acpi: update to latest version
  Staging: Clean up sxg driver
  Staging: remove remaining uses of __FUNCTION__
  Staging: add poch driver
  Staging: wlan-ng: fix build error if wireless networking is not enabled
  Staging: echo: remove annoying "end of function" markers
  Staging: echo: remove __cplusplus macro magic
  Staging: echo: remove dead code
  ...
parents 92fb83af 51b90540
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -43,4 +43,8 @@ source "drivers/staging/echo/Kconfig"

source "drivers/staging/at76_usb/Kconfig"

source "drivers/staging/pcc-acpi/Kconfig"

source "drivers/staging/poch/Kconfig"

endif # STAGING
+2 −0
Original line number Diff line number Diff line
@@ -13,3 +13,5 @@ obj-$(CONFIG_W35UND) += winbond/
obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
obj-$(CONFIG_ECHO)		+= echo/
obj-$(CONFIG_USB_ATMEL)		+= at76_usb/
obj-$(CONFIG_PCC_ACPI)		+= pcc-acpi/
obj-$(CONFIG_POCH)		+= poch/
+3 −1
Original line number Diff line number Diff line
@@ -2319,9 +2319,11 @@ static int at76_iw_handler_get_scan(struct net_device *netdev,
	if (!iwe)
		return -ENOMEM;

	if (priv->scan_state != SCAN_COMPLETED)
	if (priv->scan_state != SCAN_COMPLETED) {
		/* scan not yet finished */
		kfree(iwe);
		return -EAGAIN;
	}

	spin_lock_irqsave(&priv->bss_list_spinlock, flags);

+90 −115
Original line number Diff line number Diff line
@@ -30,10 +30,6 @@
#if !defined(_BIT_OPERATIONS_H_)
#define _BIT_OPERATIONS_H_

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__i386__)  ||  defined(__x86_64__)
/*! \brief Find the bit position of the highest set bit in a word
    \param bits The word to be searched
@@ -46,10 +42,10 @@ static __inline__ int top_bit(unsigned int bits)
		" decl %[res];\n"
		" bsrl %[bits],%[res]\n"
		:[res] "=&r" (res)
             : [bits] "rm" (bits));
		:[bits] "rm"(bits)
	);
	return res;
}
/*- End of function --------------------------------------------------------*/

/*! \brief Find the bit position of the lowest set bit in a word
    \param bits The word to be searched
@@ -62,10 +58,10 @@ static __inline__ int bottom_bit(unsigned int bits)
		" decl %[res];\n"
		" bsfl %[bits],%[res]\n"
		:[res] "=&r" (res)
             : [bits] "rm" (bits));
		:[bits] "rm"(bits)
	);
	return res;
}
/*- End of function --------------------------------------------------------*/
#else
static __inline__ int top_bit(unsigned int bits)
{
@@ -74,34 +70,28 @@ static __inline__ int top_bit(unsigned int bits)
	if (bits == 0)
		return -1;
	i = 0;
    if (bits & 0xFFFF0000)
    {
	if (bits & 0xFFFF0000) {
		bits &= 0xFFFF0000;
		i += 16;
	}
    if (bits & 0xFF00FF00)
    {
	if (bits & 0xFF00FF00) {
		bits &= 0xFF00FF00;
		i += 8;
	}
    if (bits & 0xF0F0F0F0)
    {
	if (bits & 0xF0F0F0F0) {
		bits &= 0xF0F0F0F0;
		i += 4;
	}
    if (bits & 0xCCCCCCCC)
    {
	if (bits & 0xCCCCCCCC) {
		bits &= 0xCCCCCCCC;
		i += 2;
	}
    if (bits & 0xAAAAAAAA)
    {
	if (bits & 0xAAAAAAAA) {
		bits &= 0xAAAAAAAA;
		i += 1;
	}
	return i;
}
/*- End of function --------------------------------------------------------*/

static __inline__ int bottom_bit(unsigned int bits)
{
@@ -110,34 +100,28 @@ static __inline__ int bottom_bit(unsigned int bits)
	if (bits == 0)
		return -1;
	i = 32;
    if (bits & 0x0000FFFF)
    {
	if (bits & 0x0000FFFF) {
		bits &= 0x0000FFFF;
		i -= 16;
	}
    if (bits & 0x00FF00FF)
    {
	if (bits & 0x00FF00FF) {
		bits &= 0x00FF00FF;
		i -= 8;
	}
    if (bits & 0x0F0F0F0F)
    {
	if (bits & 0x0F0F0F0F) {
		bits &= 0x0F0F0F0F;
		i -= 4;
	}
    if (bits & 0x33333333)
    {
	if (bits & 0x33333333) {
		bits &= 0x33333333;
		i -= 2;
	}
    if (bits & 0x55555555)
    {
	if (bits & 0x55555555) {
		bits &= 0x55555555;
		i -= 1;
	}
	return i;
}
/*- End of function --------------------------------------------------------*/
#endif

/*! \brief Bit reverse a byte.
@@ -147,7 +131,8 @@ static __inline__ uint8_t bit_reverse8(uint8_t x)
{
#if defined(__i386__)  ||  defined(__x86_64__)
	/* If multiply is fast */
    return ((x*0x0802U & 0x22110U) | (x*0x8020U & 0x88440U))*0x10101U >> 16;
	return ((x * 0x0802U & 0x22110U) | (x * 0x8020U & 0x88440U)) *
	    0x10101U >> 16;
#else
	/* If multiply is slow, but we have a barrel shifter */
	x = (x >> 4) | (x << 4);
@@ -155,7 +140,6 @@ static __inline__ uint8_t bit_reverse8(uint8_t x)
	return ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
#endif
}
/*- End of function --------------------------------------------------------*/

/*! \brief Bit reverse a 16 bit word.
    \param data The word to be reversed.
@@ -195,7 +179,6 @@ static __inline__ uint32_t least_significant_one32(uint32_t x)
{
	return (x & (-(int32_t) x));
}
/*- End of function --------------------------------------------------------*/

/*! \brief Find the most significant one in a word, and return a word
           with just that bit set.
@@ -210,7 +193,6 @@ static __inline__ uint32_t most_significant_one32(uint32_t x)
	return (x ^ (x >> 1));
#endif
}
/*- End of function --------------------------------------------------------*/

/*! \brief Find the parity of a byte.
    \param x The byte to be checked.
@@ -220,7 +202,6 @@ static __inline__ int parity8(uint8_t x)
	x = (x ^ (x >> 4)) & 0x0F;
	return (0x6996 >> x) & 1;
}
/*- End of function --------------------------------------------------------*/

/*! \brief Find the parity of a 16 bit word.
    \param x The word to be checked.
@@ -231,7 +212,6 @@ static __inline__ int parity16(uint16_t x)
	x = (x ^ (x >> 4)) & 0x0F;
	return (0x6996 >> x) & 1;
}
/*- End of function --------------------------------------------------------*/

/*! \brief Find the parity of a 32 bit word.
    \param x The word to be checked.
@@ -243,11 +223,6 @@ static __inline__ int parity32(uint32_t x)
	x = (x ^ (x >> 4)) & 0x0F;
	return (0x6996 >> x) & 1;
}
/*- End of function --------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif
/*- End of file ------------------------------------------------------------*/
+421 −414
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@

   Steve also has some nice notes on echo cancellers in echo.h


   References:

   [1] Ochiai, Areseki, and Ogihara, "Echo Canceller with Two Echo
@@ -109,8 +108,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#define malloc(a) kmalloc((a), GFP_KERNEL)
#define free(a) kfree(a)

#include "bit_operations.h"
#include "echo.h"
@@ -126,9 +123,9 @@

/* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */


#ifdef __BLACKFIN_ASM__
static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
#ifdef __bfin__
static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
				    int shift)
{
	int i, j;
	int offset1;
@@ -153,8 +150,7 @@ static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)

	//asm("st:");
	n = ec->taps;
    for (i = 0, j = offset2;  i < n;  i++, j++)
    {
	for (i = 0, j = offset2; i < n; i++, j++) {
		exp = *phist++ * factor;
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
	}
@@ -200,7 +196,8 @@ static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
*/

#else
static __inline__ void lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
static __inline__ void lms_adapt_bg(struct oslec_state *ec, int clean,
				    int shift)
{
	int i;

@@ -219,64 +216,50 @@ static __inline__ void lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
	offset2 = ec->curr_pos;
	offset1 = ec->taps - offset2;

    for (i = ec->taps - 1;  i >= offset1;  i--)
    {
	for (i = ec->taps - 1; i >= offset1; i--) {
		exp = (ec->fir_state_bg.history[i - offset1] * factor);
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
	}
    for (  ;  i >= 0;  i--)
    {
	for (; i >= 0; i--) {
		exp = (ec->fir_state_bg.history[i + offset2] * factor);
		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
	}
}
#endif

/*- End of function --------------------------------------------------------*/

echo_can_state_t *echo_can_create(int len, int adaption_mode)
struct oslec_state *oslec_create(int len, int adaption_mode)
{
    echo_can_state_t *ec;
	struct oslec_state *ec;
	int i;
    int j;

    ec = kmalloc(sizeof(*ec), GFP_KERNEL);
    if (ec == NULL)
	ec = kzalloc(sizeof(*ec), GFP_KERNEL);
	if (!ec)
		return NULL;
    memset(ec, 0, sizeof(*ec));

	ec->taps = len;
	ec->log2taps = top_bit(len);
	ec->curr_pos = ec->taps - 1;

    for (i = 0;  i < 2;  i++)
    {
        if ((ec->fir_taps16[i] = (int16_t *) malloc((ec->taps)*sizeof(int16_t))) == NULL)
        {
            for (j = 0;  j < i;  j++)
                kfree(ec->fir_taps16[j]);
            kfree(ec);
            return  NULL;
        }
        memset(ec->fir_taps16[i], 0, (ec->taps)*sizeof(int16_t));
	for (i = 0; i < 2; i++) {
		ec->fir_taps16[i] =
		    kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
		if (!ec->fir_taps16[i])
			goto error_oom;
	}

    fir16_create(&ec->fir_state,
                 ec->fir_taps16[0],
                 ec->taps);
    fir16_create(&ec->fir_state_bg,
                 ec->fir_taps16[1],
                 ec->taps);
	fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps);
	fir16_create(&ec->fir_state_bg, ec->fir_taps16[1], ec->taps);

	for (i = 0; i < 5; i++) {
		ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
	}

	ec->cng_level = 1000;
    echo_can_adaption_mode(ec, adaption_mode);
	oslec_adaption_mode(ec, adaption_mode);

    ec->snapshot = (int16_t*)malloc(ec->taps*sizeof(int16_t));
    memset(ec->snapshot, 0, sizeof(int16_t)*ec->taps);
	ec->snapshot = kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
	if (!ec->snapshot)
		goto error_oom;

	ec->cond_met = 0;
	ec->Pstates = 0;
@@ -288,10 +271,18 @@ echo_can_state_t *echo_can_create(int len, int adaption_mode)
	ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;

	return ec;

      error_oom:
	for (i = 0; i < 2; i++)
		kfree(ec->fir_taps16[i]);

	kfree(ec);
	return NULL;
}
/*- End of function --------------------------------------------------------*/

void echo_can_free(echo_can_state_t *ec)
EXPORT_SYMBOL_GPL(oslec_create);

void oslec_free(struct oslec_state *ec)
{
	int i;

@@ -302,15 +293,17 @@ void echo_can_free(echo_can_state_t *ec)
	kfree(ec->snapshot);
	kfree(ec);
}
/*- End of function --------------------------------------------------------*/

void echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode)
EXPORT_SYMBOL_GPL(oslec_free);

void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
{
	ec->adaption_mode = adaption_mode;
}
/*- End of function --------------------------------------------------------*/

void echo_can_flush(echo_can_state_t *ec)
EXPORT_SYMBOL_GPL(oslec_adaption_mode);

void oslec_flush(struct oslec_state *ec)
{
	int i;

@@ -334,16 +327,19 @@ void echo_can_flush(echo_can_state_t *ec)
	ec->curr_pos = ec->taps - 1;
	ec->Pstates = 0;
}
/*- End of function --------------------------------------------------------*/

void echo_can_snapshot(echo_can_state_t *ec) {
EXPORT_SYMBOL_GPL(oslec_flush);

void oslec_snapshot(struct oslec_state *ec)
{
	memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
}
/*- End of function --------------------------------------------------------*/

EXPORT_SYMBOL_GPL(oslec_snapshot);

/* Dual Path Echo Canceller ------------------------------------------------*/

int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
{
	int32_t echo_value;
	int clean_bg;
@@ -353,7 +349,8 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
	   starts clipping.  Another possible way to handle this would be the
	   filter coefficent scaling. */

    ec->tx = tx; ec->rx = rx;
	ec->tx = tx;
	ec->rx = rx;
	tx >>= 1;
	rx >>= 1;

@@ -386,8 +383,10 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
		/* hard limit filter to prevent clipping.  Note that at this stage
		   rx should be limited to +/- 16383 due to right shift above */
		tmp1 = ec->rx_1 >> 15;
      if (tmp1 > 16383) tmp1 = 16383;
      if (tmp1 < -16383) tmp1 = -16383;
		if (tmp1 > 16383)
			tmp1 = 16383;
		if (tmp1 < -16383)
			tmp1 = -16383;
		rx = tmp1;
		ec->rx_2 = tmp;
	}
@@ -404,8 +403,10 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
		new = (int)tx *(int)tx;
		old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
		    (int)ec->fir_state.history[ec->fir_state.curr_pos];
	ec->Pstates += ((new - old) + (1<<ec->log2taps)) >> ec->log2taps;
	if (ec->Pstates < 0) ec->Pstates = 0;
		ec->Pstates +=
		    ((new - old) + (1 << ec->log2taps)) >> ec->log2taps;
		if (ec->Pstates < 0)
			ec->Pstates = 0;
	}

	/* Calculate short term average levels using simple single pole IIRs */
@@ -498,34 +499,31 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)

	if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
	    (ec->nonupdate_dwell == 0) &&
	(8*ec->Lclean_bg < 7*ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
	(8*ec->Lclean_bg < ec->Ltx)      /* (ec->Lclean_bg < 0.125*ec->Ltx)    */ )
    {
	    (8 * ec->Lclean_bg <
	     7 * ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
	    (8 * ec->Lclean_bg <
	     ec->Ltx) /* (ec->Lclean_bg < 0.125*ec->Ltx)    */ ) {
		if (ec->cond_met == 6) {
			/* BG filter has had better results for 6 consecutive samples */
			ec->adapt = 1;
	    memcpy(ec->fir_taps16[0], ec->fir_taps16[1], ec->taps*sizeof(int16_t));
	}
	else
			memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
			       ec->taps * sizeof(int16_t));
		} else
			ec->cond_met++;
    }
    else
	} else
		ec->cond_met = 0;

	/* Non-Linear Processing --------------------------------------------------- */

	ec->clean_nlp = ec->clean;
    if (ec->adaption_mode & ECHO_CAN_USE_NLP)
    {
	if (ec->adaption_mode & ECHO_CAN_USE_NLP) {
		/* Non-linear processor - a fancy way to say "zap small signals, to avoid
		   residual echo due to (uLaw/ALaw) non-linearity in the channel.". */

      if ((16*ec->Lclean < ec->Ltx))
      {
		if ((16 * ec->Lclean < ec->Ltx)) {
			/* Our e/c has improved echo by at least 24 dB (each factor of 2 is 6dB,
			   so 2*2*2*2=16 is the same as 6+6+6+6=24dB) */
        if (ec->adaption_mode & ECHO_CAN_USE_CNG)
	{
			if (ec->adaption_mode & ECHO_CAN_USE_CNG) {
				ec->cng_level = ec->Lbgn;

				/* Very elementary comfort noise generation.  Just random
@@ -536,27 +534,26 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
				   high level or look at spectrum.
				 */

	    ec->cng_rndnum = 1664525U*ec->cng_rndnum + 1013904223U;
	    ec->cng_filter = ((ec->cng_rndnum & 0xFFFF) - 32768 + 5*ec->cng_filter) >> 3;
	    ec->clean_nlp = (ec->cng_filter*ec->cng_level*8) >> 14;
				ec->cng_rndnum =
				    1664525U * ec->cng_rndnum + 1013904223U;
				ec->cng_filter =
				    ((ec->cng_rndnum & 0xFFFF) - 32768 +
				     5 * ec->cng_filter) >> 3;
				ec->clean_nlp =
				    (ec->cng_filter * ec->cng_level * 8) >> 14;

        }
        else if (ec->adaption_mode & ECHO_CAN_USE_CLIP)
	{
			} else if (ec->adaption_mode & ECHO_CAN_USE_CLIP) {
				/* This sounds much better than CNG */
				if (ec->clean_nlp > ec->Lbgn)
					ec->clean_nlp = ec->Lbgn;
				if (ec->clean_nlp < -ec->Lbgn)
					ec->clean_nlp = -ec->Lbgn;
	}
	else
        {
			} else {
				/* just mute the residual, doesn't sound very good, used mainly
				   in G168 tests */
				ec->clean_nlp = 0;
			}
      }
      else {
		} else {
			/* Background noise estimator.  I tried a few algorithms
			   here without much luck.  This very simple one seems to
			   work best, we just average the level using a slow (1 sec
@@ -585,7 +582,7 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
	return (int16_t) ec->clean_nlp << 1;
}

/*- End of function --------------------------------------------------------*/
EXPORT_SYMBOL_GPL(oslec_update);

/* This function is seperated from the echo canceller is it is usually called
   as part of the tx process.  See rx HP (DC blocking) filter above, it's
@@ -608,7 +605,8 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
   precision, which noise shapes things, giving very clean DC removal.
*/

int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx) {
int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
{
	int tmp, tmp1;

	if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
@@ -622,11 +620,20 @@ int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx) {
#endif
		ec->tx_1 += -(ec->tx_1 >> DC_LOG2BETA) + tmp - ec->tx_2;
		tmp1 = ec->tx_1 >> 15;
	if (tmp1 > 32767) tmp1 = 32767;
	if (tmp1 < -32767) tmp1 = -32767;
		if (tmp1 > 32767)
			tmp1 = 32767;
		if (tmp1 < -32767)
			tmp1 = -32767;
		tx = tmp1;
		ec->tx_2 = tmp;
	}

	return tx;
}

EXPORT_SYMBOL_GPL(oslec_hpf_tx);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Rowe");
MODULE_DESCRIPTION("Open Source Line Echo Canceller");
MODULE_VERSION("0.3.0");
Loading