318 lines
8.5 KiB
C
318 lines
8.5 KiB
C
/*
|
|
* Copyright (c) 202X Amlogic, Inc. All rights reserved.
|
|
*
|
|
* This source code is subject to the terms and conditions defined in the
|
|
* file 'LICENSE' which is part of this source code package.
|
|
*
|
|
* Description:
|
|
*/
|
|
#include <linux/skbuff.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include "common.h"
|
|
#include "w2_bt_entry.h"
|
|
|
|
unsigned int g_dbg_level = LOG_LEVEL_ERROR;
|
|
unsigned int amlbt_if_type = AMLBT_TRANS_UNKNOWN;
|
|
unsigned int polling_time = 8000;
|
|
unsigned int amlbt_ft_mode = 0;
|
|
|
|
void amlbt_intf_queue_work(struct workqueue_struct *wq , struct work_struct *work)
|
|
{
|
|
if (wq == NULL)
|
|
{
|
|
BTE("%s: wq NULL\n", __func__);
|
|
}
|
|
else
|
|
{
|
|
queue_work(wq, work);
|
|
}
|
|
}
|
|
|
|
gdsl_fifo_t *gdsl_fifo_init(unsigned int len, unsigned char *base_addr)
|
|
{
|
|
gdsl_fifo_t *p_fifo = (gdsl_fifo_t *)kzalloc(sizeof(gdsl_fifo_t), GFP_DMA|GFP_ATOMIC);
|
|
BTA("%s \n", __func__);
|
|
if (p_fifo == NULL)
|
|
{
|
|
BTE("gdsl_fifo_init alloc error!\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
memset(p_fifo, 0, sizeof(gdsl_fifo_t));
|
|
p_fifo->w = 0;
|
|
p_fifo->r = 0;
|
|
p_fifo->base_addr = base_addr;
|
|
p_fifo->size = len;
|
|
}
|
|
return p_fifo;
|
|
}
|
|
|
|
void gdsl_fifo_deinit(gdsl_fifo_t *p_fifo)
|
|
{
|
|
if (p_fifo == NULL)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
kfree(p_fifo);
|
|
}
|
|
|
|
unsigned int gdsl_fifo_used(gdsl_fifo_t *p_fifo)
|
|
{
|
|
if (p_fifo->r <= p_fifo->w)
|
|
return (p_fifo->w - p_fifo->r);
|
|
|
|
return (p_fifo->size + p_fifo->w - p_fifo->r);
|
|
}
|
|
|
|
unsigned int gdsl_fifo_used_size(gdsl_fifo_t *p_fifo)
|
|
{
|
|
if (p_fifo->w == p_fifo->r)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (p_fifo->w > p_fifo->r)
|
|
{
|
|
return (p_fifo->w - p_fifo->r);
|
|
}
|
|
|
|
if (p_fifo->w < p_fifo->r)
|
|
{
|
|
return (p_fifo->size - (p_fifo->r - p_fifo->w));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned int gdsl_fifo_remain(gdsl_fifo_t *p_fifo)
|
|
{
|
|
unsigned int used = gdsl_fifo_used(p_fifo);
|
|
|
|
return p_fifo->size - used - 4;
|
|
}
|
|
|
|
#if 0
|
|
unsigned int gdsl_fifo_copy_data(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int i = 0;
|
|
BTA("copy d %d, %#x, %#x\n", len, p_fifo->base_addr, p_fifo->w);
|
|
|
|
if (gdsl_fifo_remain(p_fifo) < len)
|
|
{
|
|
BTE("gdsl_fifo_copy_data no space!!\n");
|
|
BTE("fifo->base_addr %#x, fifo->size %#x\n", (unsigned long)p_fifo->base_addr, p_fifo->size);
|
|
BTE("fifo->w %#x, fifo->r %#x\n", (unsigned long)p_fifo->w, (unsigned long)p_fifo->r);
|
|
BTE("remain %#x, len %#x\n", gdsl_fifo_remain(p_fifo), len);
|
|
return 0;
|
|
}
|
|
|
|
while (i < len)
|
|
{
|
|
*(unsigned char *)((unsigned long)p_fifo->w + (unsigned long)p_fifo->base_addr) = buff[i];
|
|
p_fifo->w = (unsigned char *)(((unsigned long)p_fifo->w + 1) % p_fifo->size);
|
|
i++;
|
|
}
|
|
|
|
BTA("actual len %#x \n", __func__, i);
|
|
|
|
return i;
|
|
}
|
|
#else
|
|
unsigned int gdsl_fifo_copy_data(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int i = 0;
|
|
unsigned long offset = (unsigned long)p_fifo->w;
|
|
|
|
BTA("copy d %d, %#x, %#x\n", len, p_fifo->base_addr, p_fifo->w);
|
|
|
|
if (gdsl_fifo_remain(p_fifo) < len)
|
|
{
|
|
BTE("gdsl_fifo_copy_data no space!!\n");
|
|
BTE("fifo->base_addr %#x, fifo->size %#x\n", (unsigned long)p_fifo->base_addr, p_fifo->size);
|
|
BTE("fifo->w %#x, fifo->r %#x\n", (unsigned long)p_fifo->w, (unsigned long)p_fifo->r);
|
|
BTE("remain %#x, len %#x\n", gdsl_fifo_remain(p_fifo), len);
|
|
return -1;
|
|
}
|
|
|
|
if (len < (p_fifo->size - offset))
|
|
{
|
|
memcpy((unsigned char *)((unsigned long)p_fifo->w + (unsigned long)p_fifo->base_addr), buff, len);
|
|
p_fifo->w = (unsigned char *)(((unsigned long)p_fifo->w + len) % p_fifo->size);
|
|
}
|
|
else
|
|
{
|
|
memcpy((unsigned char *)((unsigned long)p_fifo->w + (unsigned long)p_fifo->base_addr), buff, p_fifo->size - offset);
|
|
memcpy((unsigned char *)((unsigned long)p_fifo->base_addr), &buff[p_fifo->size - offset], len - (p_fifo->size - offset));
|
|
p_fifo->w = (unsigned char *)((len - (p_fifo->size - offset)) % p_fifo->size);
|
|
}
|
|
|
|
BTA("actual len %#x \n", i);
|
|
|
|
return len;
|
|
}
|
|
#endif
|
|
#if 0
|
|
unsigned int gdsl_fifo_calc_r(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int used = gdsl_fifo_used(p_fifo);
|
|
unsigned int i = 0;
|
|
unsigned int get_len = (len >= used ? used : len);
|
|
|
|
BTA("get d %d, %#x, %#x\n", get_len, p_fifo->base_addr, p_fifo->w);
|
|
if (used == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while (i < get_len)
|
|
{
|
|
p_fifo->r = (unsigned char *)(((unsigned long)p_fifo->r + 1) % p_fifo->size);
|
|
i++;
|
|
}
|
|
|
|
BTA("actual len %#x \n", __func__, i);
|
|
|
|
return i;
|
|
}
|
|
#else
|
|
unsigned int gdsl_fifo_calc_r(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int used = gdsl_fifo_used(p_fifo);
|
|
unsigned int i = 0;
|
|
unsigned int get_len = (len >= used ? used : len);
|
|
unsigned long offset = (unsigned long)p_fifo->r;
|
|
|
|
BTA("get d %d, %#x, %#x\n", get_len, p_fifo->base_addr, p_fifo->w);
|
|
if (used == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (get_len < (p_fifo->size - offset))
|
|
{
|
|
p_fifo->r = (unsigned char *)(((unsigned long)p_fifo->r + get_len) % p_fifo->size);
|
|
}
|
|
else
|
|
{
|
|
p_fifo->r = (unsigned char *)((get_len - (p_fifo->size - offset)) % p_fifo->size);
|
|
}
|
|
|
|
BTA("actual len %#x \n", i);
|
|
|
|
return get_len;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
unsigned int gdsl_fifo_update_r(gdsl_fifo_t *p_fifo, unsigned int len)
|
|
{
|
|
unsigned int offset = 0;
|
|
unsigned int read_len = 0;
|
|
unsigned char *p_end = 0;
|
|
|
|
//BTA("%s p_fifo->w %#x, p_fifo->r %#x\n", __func__, (unsigned long)p_fifo->w, (unsigned long)p_fifo->r);
|
|
//BTA("%s len %d\n", __func__, len);
|
|
|
|
if (p_fifo->w == p_fifo->r)
|
|
{
|
|
BTE("%s no data!!!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
if (p_fifo->w > p_fifo->r)
|
|
{
|
|
read_len = (unsigned int)(p_fifo->w - p_fifo->r);
|
|
if (len <= read_len)
|
|
{
|
|
read_len = len;
|
|
}
|
|
//BTA("%s read len A %d\n", __func__, read_len);
|
|
p_fifo->r += read_len;
|
|
}
|
|
else
|
|
{
|
|
p_end = (p_fifo->base_addr + p_fifo->size);
|
|
BTA("%s w %#x, r %#x\n", __func__, (unsigned long)p_fifo->w, (unsigned long)p_fifo->r);
|
|
BTA("%s read p_end %#x\n", __func__, (unsigned long)p_end);
|
|
offset = (unsigned int)(p_end - p_fifo->r);
|
|
read_len = offset;
|
|
if (len < offset)
|
|
{
|
|
p_fifo->r += len;
|
|
read_len = len;
|
|
BTA("%s 111 len %#x \n", __func__, len);
|
|
}
|
|
else
|
|
{
|
|
p_fifo->r = p_fifo->base_addr;
|
|
read_len += (len - offset);
|
|
p_fifo->r += (len - offset);
|
|
BTA("%s 222 len %#x \n", __func__, len);
|
|
}
|
|
//BTA("%s read len B %#x \n", __func__, read_len);
|
|
}
|
|
|
|
//BTA("%s actual len %#x \n", __func__, read_len);
|
|
|
|
return read_len;
|
|
}
|
|
#if 0
|
|
unsigned int gdsl_fifo_get_data(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int used = gdsl_fifo_used(p_fifo);
|
|
unsigned int i = 0;
|
|
unsigned int get_len = (len >= used ? used : len);
|
|
|
|
BTD("get d %d, %#x, %#x %#x\n", get_len, p_fifo->base_addr, p_fifo->w, p_fifo->r);
|
|
if (used == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while (i < get_len)
|
|
{
|
|
buff[i] = *(unsigned char *)((unsigned long)p_fifo->r + (unsigned long)p_fifo->base_addr);
|
|
p_fifo->r = (unsigned char *)(((unsigned long)p_fifo->r + 1) % p_fifo->size);
|
|
i++;
|
|
}
|
|
|
|
BTA("actual len %s %#x \n", __func__, i);
|
|
|
|
return i;
|
|
}
|
|
#else
|
|
unsigned int gdsl_fifo_get_data(gdsl_fifo_t *p_fifo, unsigned char *buff, unsigned int len)
|
|
{
|
|
unsigned int used = gdsl_fifo_used(p_fifo);
|
|
unsigned int i = 0;
|
|
unsigned int get_len = (len >= used ? used : len);
|
|
unsigned long offset = (unsigned long)p_fifo->r;
|
|
|
|
BTD("get d %d, %#x, %#x %#x\n", get_len, p_fifo->base_addr, p_fifo->w, p_fifo->r);
|
|
if (used == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (get_len < (p_fifo->size - offset))
|
|
{
|
|
memcpy(buff, (unsigned char *)((unsigned long)p_fifo->r + (unsigned long)p_fifo->base_addr), get_len);
|
|
p_fifo->r = (unsigned char *)(((unsigned long)p_fifo->r + get_len) % p_fifo->size);
|
|
}
|
|
else
|
|
{
|
|
memcpy(buff, (unsigned char *)((unsigned long)p_fifo->r + (unsigned long)p_fifo->base_addr), (p_fifo->size - offset));
|
|
memcpy(&buff[p_fifo->size - offset], (unsigned char *)((unsigned long)p_fifo->base_addr), (get_len - (p_fifo->size - offset)));
|
|
p_fifo->r = (unsigned char *)((get_len - (p_fifo->size - offset)) % p_fifo->size);
|
|
}
|
|
|
|
BTA("actual len %s %#x \n", __func__, i);
|
|
|
|
return get_len;
|
|
}
|
|
#endif
|