Add support for the GCT Semiconductor GRF5101 transceiver/synthesizer.
From OpenBSD. GCT will not provide any documentation, so there are many magic numbers in this code.
This commit is contained in:
parent
6910fdde2a
commit
92e2a6beb6
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtw.c,v 1.63 2005/12/29 22:23:52 dyoung Exp $ */
|
||||
/* $NetBSD: rtw.c,v 1.64 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.63 2005/12/29 22:23:52 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.64 2005/12/29 22:27:17 dyoung Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
@ -3967,6 +3967,10 @@ rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy)
|
||||
}
|
||||
|
||||
switch (rfchipid) {
|
||||
case RTW_RFCHIPID_GCT:
|
||||
rf = rtw_grf5101_create(&sc->sc_regs, rf_write, 0);
|
||||
sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
|
||||
break;
|
||||
case RTW_RFCHIPID_MAXIM:
|
||||
rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
|
||||
sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwphy.c,v 1.7 2005/12/11 12:21:28 christos Exp $ */
|
||||
/* $NetBSD: rtwphy.c,v 1.8 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.7 2005/12/11 12:21:28 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.8 2005/12/29 22:27:17 dyoung Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -61,6 +61,13 @@ __KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.7 2005/12/11 12:21:28 christos Exp $");
|
||||
static int rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
|
||||
static int rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
|
||||
|
||||
#define GCT_WRITE(__gr, __addr, __val, __label) \
|
||||
do { \
|
||||
if (rtw_rfbus_write(&(__gr)->gr_bus, RTW_RFCHIPID_GCT, \
|
||||
(__addr), (__val)) == -1) \
|
||||
goto __label; \
|
||||
} while(0)
|
||||
|
||||
static int
|
||||
rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb,
|
||||
u_int freq)
|
||||
@ -451,6 +458,175 @@ rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy)
|
||||
return &sa->sa_rf;
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_grf5101_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
|
||||
{
|
||||
struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
|
||||
|
||||
GCT_WRITE(gr, 0x15, 0, err);
|
||||
GCT_WRITE(gr, 0x06, opaque_txpower, err);
|
||||
GCT_WRITE(gr, 0x15, 0x10, err);
|
||||
GCT_WRITE(gr, 0x15, 0x00, err);
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_grf5101_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
|
||||
{
|
||||
struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
|
||||
switch (power) {
|
||||
case RTW_OFF:
|
||||
case RTW_SLEEP:
|
||||
GCT_WRITE(gr, 0x07, 0x0000, err);
|
||||
GCT_WRITE(gr, 0x1f, 0x0045, err);
|
||||
GCT_WRITE(gr, 0x1f, 0x0005, err);
|
||||
GCT_WRITE(gr, 0x00, 0x08e4, err);
|
||||
default:
|
||||
break;
|
||||
case RTW_ON:
|
||||
GCT_WRITE(gr, 0x1f, 0x0001, err);
|
||||
DELAY(10);
|
||||
GCT_WRITE(gr, 0x1f, 0x0001, err);
|
||||
DELAY(10);
|
||||
GCT_WRITE(gr, 0x1f, 0x0041, err);
|
||||
DELAY(10);
|
||||
GCT_WRITE(gr, 0x1f, 0x0061, err);
|
||||
DELAY(10);
|
||||
GCT_WRITE(gr, 0x00, 0x0ae4, err);
|
||||
DELAY(10);
|
||||
GCT_WRITE(gr, 0x07, 0x1000, err);
|
||||
DELAY(100);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_grf5101_tune(struct rtw_rf *rf, u_int freq)
|
||||
{
|
||||
int channel;
|
||||
struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
|
||||
|
||||
if (freq == 2484)
|
||||
channel = 14;
|
||||
else if ((channel = (freq - 2412) / 5 + 1) < 1 || channel > 13) {
|
||||
RTW_DPRINTF(RTW_DEBUG_PHY,
|
||||
("%s: invalid channel %d (freq %d)\n", __func__, channel,
|
||||
freq));
|
||||
return -1;
|
||||
}
|
||||
|
||||
GCT_WRITE(gr, 0x07, 0, err);
|
||||
GCT_WRITE(gr, 0x0b, channel - 1, err);
|
||||
GCT_WRITE(gr, 0x07, 0x1000, err);
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_grf5101_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
|
||||
enum rtw_pwrstate power)
|
||||
{
|
||||
int rc;
|
||||
struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
|
||||
|
||||
/*
|
||||
* These values have been derived from the rtl8180-sa2400
|
||||
* Linux driver. It is unknown what they all do, GCT refuse
|
||||
* to release any documentation so these are more than
|
||||
* likely sub optimal settings
|
||||
*/
|
||||
|
||||
GCT_WRITE(gr, 0x01, 0x1a23, err);
|
||||
GCT_WRITE(gr, 0x02, 0x4971, err);
|
||||
GCT_WRITE(gr, 0x03, 0x41de, err);
|
||||
GCT_WRITE(gr, 0x04, 0x2d80, err);
|
||||
|
||||
GCT_WRITE(gr, 0x05, 0x61ff, err);
|
||||
|
||||
GCT_WRITE(gr, 0x06, 0x0, err);
|
||||
|
||||
GCT_WRITE(gr, 0x08, 0x7533, err);
|
||||
GCT_WRITE(gr, 0x09, 0xc401, err);
|
||||
GCT_WRITE(gr, 0x0a, 0x0, err);
|
||||
GCT_WRITE(gr, 0x0c, 0x1c7, err);
|
||||
GCT_WRITE(gr, 0x0d, 0x29d3, err);
|
||||
GCT_WRITE(gr, 0x0e, 0x2e8, err);
|
||||
GCT_WRITE(gr, 0x10, 0x192, err);
|
||||
GCT_WRITE(gr, 0x11, 0x248, err);
|
||||
GCT_WRITE(gr, 0x12, 0x0, err);
|
||||
GCT_WRITE(gr, 0x13, 0x20c4, err);
|
||||
GCT_WRITE(gr, 0x14, 0xf4fc, err);
|
||||
GCT_WRITE(gr, 0x15, 0x0, err);
|
||||
GCT_WRITE(gr, 0x16, 0x1500, err);
|
||||
|
||||
if ((rc = rtw_grf5101_txpower(rf, opaque_txpower)) != 0)
|
||||
return rc;
|
||||
|
||||
if ((rc = rtw_grf5101_tune(rf, freq)) != 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
rtw_grf5101_destroy(struct rtw_rf *rf)
|
||||
{
|
||||
struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
|
||||
memset(gr, 0, sizeof(*gr));
|
||||
free(gr, M_DEVBUF);
|
||||
}
|
||||
|
||||
struct rtw_rf *
|
||||
rtw_grf5101_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy)
|
||||
{
|
||||
struct rtw_grf5101 *gr;
|
||||
struct rtw_rfbus *bus;
|
||||
struct rtw_rf *rf;
|
||||
struct rtw_bbpset *bb;
|
||||
|
||||
gr = malloc(sizeof(*gr), M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (gr == NULL)
|
||||
return NULL;
|
||||
|
||||
rf = &gr->gr_rf;
|
||||
bus = &gr->gr_bus;
|
||||
|
||||
rf->rf_init = rtw_grf5101_init;
|
||||
rf->rf_destroy = rtw_grf5101_destroy;
|
||||
rf->rf_txpower = rtw_grf5101_txpower;
|
||||
rf->rf_tune = rtw_grf5101_tune;
|
||||
rf->rf_pwrstate = rtw_grf5101_pwrstate;
|
||||
bb = &rf->rf_bbpset;
|
||||
|
||||
/* XXX magic */
|
||||
bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC;
|
||||
bb->bb_chestlim = 0x00;
|
||||
bb->bb_chsqlim = 0xa0;
|
||||
bb->bb_ifagcdet = 0x64;
|
||||
bb->bb_ifagcini = 0x90;
|
||||
bb->bb_ifagclimit = 0x1e;
|
||||
bb->bb_lnadet = 0xc0;
|
||||
bb->bb_sys1 = 0xa8;
|
||||
bb->bb_sys2 = 0x47;
|
||||
bb->bb_sys3 = 0x9b;
|
||||
bb->bb_trl = 0x88;
|
||||
bb->bb_txagc = 0x08;
|
||||
|
||||
bus->b_regs = regs;
|
||||
bus->b_write = rf_write;
|
||||
|
||||
return &gr->gr_rf;
|
||||
}
|
||||
|
||||
/* freq is in MHz */
|
||||
static int
|
||||
rtw_max2820_tune(struct rtw_rf *rf, u_int freq)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwphy.h,v 1.4 2005/12/11 12:21:28 christos Exp $ */
|
||||
/* $NetBSD: rtwphy.h,v 1.5 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -32,6 +32,7 @@
|
||||
#ifndef _DEV_IC_RTWPHY_H
|
||||
#define _DEV_IC_RTWPHY_H
|
||||
|
||||
struct rtw_rf *rtw_grf5101_create(struct rtw_regs *, rtw_rf_write_t, int);
|
||||
struct rtw_rf *rtw_sa2400_create(struct rtw_regs *, rtw_rf_write_t, int);
|
||||
struct rtw_rf *rtw_max2820_create(struct rtw_regs *, rtw_rf_write_t, int);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwphyio.c,v 1.9 2005/12/24 20:27:30 perry Exp $ */
|
||||
/* $NetBSD: rtwphyio.c,v 1.10 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtwphyio.c,v 1.9 2005/12/24 20:27:30 perry Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtwphyio.c,v 1.10 2005/12/29 22:27:17 dyoung Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -273,15 +273,17 @@ rtw_rf_hostwrite(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
|
||||
lo_to_hi = 1;
|
||||
break;
|
||||
case RTW_RFCHIPID_GCT:
|
||||
KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
|
||||
KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
|
||||
bits = rtw_grf5101_host_crypt(addr, val);
|
||||
nbits = 21;
|
||||
lo_to_hi = 1;
|
||||
break;
|
||||
case RTW_RFCHIPID_RFMD:
|
||||
KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
|
||||
KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
|
||||
if (rfchipid == RTW_RFCHIPID_GCT)
|
||||
bits = rtw_grf5101_host_crypt(addr, val);
|
||||
else {
|
||||
bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
|
||||
LSHIFT(addr, SI4126_TWI_ADDR_MASK);
|
||||
}
|
||||
bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
|
||||
LSHIFT(addr, SI4126_TWI_ADDR_MASK);
|
||||
nbits = 22;
|
||||
lo_to_hi = 0;
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwreg.h,v 1.15 2005/12/13 05:10:55 dyoung Exp $ */
|
||||
/* $NetBSD: rtwreg.h,v 1.16 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -1116,6 +1116,7 @@ struct rtw_rxdesc {
|
||||
*/
|
||||
|
||||
#define RTW_BBP_ANTATTEN 0x10 /* guess: antenna & attenuation */
|
||||
#define RTW_BBP_ANTATTEN_GCT_MAGIC 0xa3
|
||||
#define RTW_BBP_ANTATTEN_PHILIPS_MAGIC 0x91
|
||||
#define RTW_BBP_ANTATTEN_INTERSIL_MAGIC 0x92
|
||||
#define RTW_BBP_ANTATTEN_RFMD_MAGIC 0x93
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwvar.h,v 1.26 2005/12/24 20:27:30 perry Exp $ */
|
||||
/* $NetBSD: rtwvar.h,v 1.27 2005/12/29 22:27:17 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -374,6 +374,11 @@ struct rtw_max2820 {
|
||||
int mx_is_a; /* 1: MAX2820A/MAX2821A */
|
||||
};
|
||||
|
||||
struct rtw_grf5101 {
|
||||
struct rtw_rf gr_rf;
|
||||
struct rtw_rfbus gr_bus;
|
||||
};
|
||||
|
||||
struct rtw_sa2400 {
|
||||
struct rtw_rf sa_rf;
|
||||
struct rtw_rfbus sa_bus;
|
||||
|
Loading…
Reference in New Issue
Block a user