Files
luban-lite/bsp/peripheral/wireless/hugeic/porting/jxc_rtt/sdio.c
刘可亮 3e10f578d3 v1.2.2
2025-10-21 13:59:50 +08:00

349 lines
8.5 KiB
C

#include "os_porting.h"
#include "drivers/mmcsd_card.h"
#include "drivers/mmcsd_core.h"
#include "drivers/sdio.h"
#include "os_sdio.h"
#include "plat_gpio.h"
#define HGIC_VENDOR_ID (0xA012)
#define HGIC_WLAN_4001 (0x4001)
#define HGIC_WLAN_4002 (0x4002)
#define HGIC_WLAN_4102 (0x4102)
#define HGIC_WLAN_4103 (0x4103)
#define HGIC_WLAN_4104 (0x4104)
#define HGIC_WLAN_8400 (0x8400)
#define HGIC_WLAN_8410 (0x8410)
#define HGIC_WLAN_8000 (0x8000)
#define SDIO_DEVICE(vend,dev) \
.manufacturer = (vend), .product = (dev)
//typedef rt_sdio_irq_handler_t sdio_irq_handler_t;
const struct rt_sdio_device_id hgic_sdio_wdev_ids[] = {
{SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4002)},
{SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4104)},
{SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_8400)},
{SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_8410)},
{SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_8000)},
{ /* end: all zeroes */ },
};
unsigned char *malloc_sdio_rxbuf(unsigned int buff_len,unsigned int flags)
{
return rt_malloc(buff_len);//maybe align
}
void free_sdio_rxbuf(unsigned char *rxbuf)
{
if(rxbuf) {
rt_free(rxbuf);
}
}
unsigned char sys_sdio_readb(sdio_func_t *func, unsigned long addr, int *err)
{
return sdio_io_readb(func, (rt_uint32_t)addr, (rt_int32_t *)err);
}
unsigned char sys_sdio_writeb(sdio_func_t *func, unsigned char b, unsigned long addr, int *err)
{
int ret = 0;
ret = sdio_io_writeb(func, (rt_uint32_t)addr, b);
if (err) {
*err = ret;
}
return 0;
}
static int hgic_sdio_readb(sdio_func_t *func, unsigned int addr, int *err)
{
unsigned char val = 0;
int retry = 2;
val = sys_sdio_readb(func, addr, err);
while (*err && retry-- > 0) {
val = sys_sdio_readb(func, addr, err);
}
return val;
}
static void hgic_sdio_writeb(sdio_func_t *func, unsigned char b, unsigned int addr, int *err)
{
int retry = 4;
do {
sys_sdio_writeb(func, b, addr, err);
} while (*err && retry-- > 0);
}
int hgic_sdio_abort(sdio_func_t *func)
{
int err_ret = 0;
struct rt_sdio_function func0;
rt_memcpy(&func0, func, sizeof(func0));
func0.num = 0;
hgic_sdio_writeb(&func0, 1, 6, &err_ret);
return err_ret;
}
int hgic_sdio_read_cccr(sdio_func_t *func, unsigned char *pending)
{
int ret = 0;
struct rt_sdio_function func0;
rt_memcpy(&func0, func, sizeof(func0));
func0.num = 0;
*pending = hgic_sdio_readb(&func0, 0x5, &ret);
return ret;
}
long sys_sdio_memcpy_fromio(sdio_func_t *func, unsigned char *dest, unsigned long addr, int count)
{
return sdio_io_read_multi_incr_b(func, addr, dest, count);
}
long sys_sdio_memcpy_toio(sdio_func_t *func, unsigned long addr, unsigned char *src, int count)
{
return sdio_io_write_multi_incr_b(func, addr, src, count);
}
void sys_sdio_claim_host(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
mmcsd_host_lock(sdio_func->card->host);
}
void sys_sdio_release_host(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
mmcsd_host_unlock(sdio_func->card->host);
}
long sys_sdio_set_block_size(sdio_func_t *func, int bsize)
{
long ret = 0;
ret = sdio_set_block_size(func,bsize);
if (ret) {
hgic_err("Set sdio blocksize failed:%d,blocksize:%d\n", ret, bsize);
} else {
hgic_dbg("Set sdio blocksize:%d\n", bsize);
}
return ret;
}
long sys_sdio_enable_func(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
long ret = 0;
ret = sdio_enable_func(sdio_func);
if (ret) {
hgic_dbg("enable: function%d failed!\n", sdio_func->num);
} else {
hgic_dbg("sys_sdio_enable_func: function%d enabled.\n", sdio_func->num);
}
return ret;
}
long sys_sdio_disable_func(sdio_func_t *func)
{
return sdio_disable_func(func);
}
long sys_sdio_claim_irq(sdio_func_t *func, sdio_irq_handler_t irqhdl)
{
return sdio_attach_irq(func, irqhdl);
}
long sys_sdio_release_irq(sdio_func_t *func)
{
return sdio_detach_irq(func);
}
void *sys_sdio_get_drvdata(sdio_func_t *func)
{
return (void *)sdio_get_drvdata(func);
}
long sys_sdio_set_drvdata(sdio_func_t *func, void *data)
{
sdio_set_drvdata(func, data);
return 0;
}
/*
long sys_sdio_register_driver(sdio_driver_t *driver)
{
return sdio_register_driver((struct rt_sdio_driver *)driver)
}
void sys_sdio_unregister_driver(sdio_driver_t *driver)
{
;
}
unsigned short hgic_get_func_rca(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
ASSERT(sdio_func);
ASSERT(sdio_func->card);
return sdio_func->card->rca;
}
*/
unsigned long sys_sdio_get_func_num(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
return sdio_func->num;
}
void *sys_sdio_get_func_dev(sdio_func_t *func)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
return (void *)sdio_func->card;
}
unsigned short sys_sdio_get_device_id(sdio_device_id_t *id)
{
struct rt_sdio_device_id *devid = (struct rt_sdio_device_id *)id;
return devid->product;
}
unsigned short sys_sdio_get_vendor_id(sdio_device_id_t *id)
{
struct rt_sdio_device_id *devid = (struct rt_sdio_device_id *)id;
return devid->manufacturer;
}
void hgic_mmc_set_blk_size(sdio_func_t *func, unsigned int blk_size)
{
sdio_set_block_size(func, blk_size);
}
void hgic_mmc_set_clock(sdio_func_t *func, unsigned int hz)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
ASSERT(sdio_func);
ASSERT(sdio_func->card);
ASSERT(sdio_func->card->host);
mmcsd_set_clock(sdio_func->card->host, hz);
}
void hgic_mmc_set_timing(sdio_func_t *func, unsigned int timing)
{
// do nothing
}
void hgic_mmc_set_bus_width(sdio_func_t *func, unsigned int width)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
ASSERT(sdio_func);
ASSERT(sdio_func->card);
ASSERT(sdio_func->card->host);
mmcsd_set_bus_width(sdio_func->card->host, width);
}
#if 0
long hgic_mmc_io_rw_direct(sdio_func_t *func, int write, unsigned fn, unsigned addr, unsigned char in, unsigned char *out)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
ASSERT(out)
ASSERT(sdio_func);
ASSERT(sdio_func->card);
//return sdio_io_rw_direct(sdio_func->card, write, fn, addr, write?&in:out, 0);
return sdio_io_rw_direct(sdio_func->card, write, fn, addr, out, out);
}
#endif
long hgic_mmc_send_cmd(sdio_func_t *func, void *cmd, int retries)
{
struct rt_sdio_function *sdio_func = (struct rt_sdio_function *)func;
struct rt_mmcsd_cmd *command = (struct rt_mmcsd_cmd *)cmd;
int err = 0;
ASSERT(sdio_func);
ASSERT(sdio_func->card);
ASSERT(sdio_func->card->host);
ASSERT(command);
err = mmcsd_send_cmd(sdio_func->card->host, command, retries);
if (err) {
hgic_err("cmd:%d Error\n",command->cmd_code);
return err;
}
return 0;
}
unsigned long hgic_sdio_get_max_clock(sdio_func_t *func)
{
return 50000000;
}
typedef int (*hgic_probe)(void *dev, void *bus);
extern int hgic_sdio_probe(sdio_func_t *func, const sdio_device_id_t *id);
extern void hgic_sdio_remove(sdio_func_t *func);
extern void hgic_sdio_set_probe_hdl(hgic_probe probe);
extern unsigned int hgic_sdio_set_max_pkt(unsigned int max_pkt);
static rt_int32_t hgic_sdio_probe_rtt(struct rt_mmcsd_card *card)
{
rt_int32_t ret = 0;
sdio_func_t *func = card->sdio_function[1];
sdio_device_id_t id;
id.manufacturer = card->sdio_function[1]->manufacturer;
id.product = card->sdio_function[1]->product;
ret = hgic_sdio_probe(func, &id);
if (ret)
hgic_dbg("sdio probe faile!\n");
return ret;
}
static rt_int32_t hgic_sdio_remove_rtt(struct rt_mmcsd_card *card)
{
sdio_func_t *func = card->sdio_function[1];
hgic_sdio_remove(func);
return 0;
}
static struct rt_sdio_driver hgic_sdio_driver = {
.name = "hgic_sdio_wlan",
//.id = hgic_sdio_wdev_ids,
.probe = hgic_sdio_probe_rtt,
.remove = hgic_sdio_remove_rtt,
};
int hgic_sdio_init(hgic_probe probe, unsigned int max_pkt)
{
int ret;
hgic_sdio_set_probe_hdl(probe);
hgic_sdio_set_max_pkt(max_pkt);
hgic_sdio_driver.id = &hgic_sdio_wdev_ids[4];
ret = sdio_register_driver(&hgic_sdio_driver);
if (ret) {
hgic_err("hgicf sdio register driver failed! ret = %d\n", ret);
return;
}
return ret;
}
void hgic_sdio_exit(void)
{
sdio_unregister_driver(&hgic_sdio_driver);
}