mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-28 17:12:22 +00:00
Compare commits
70 Commits
staging-WI
...
staging-WI
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dc88abf4f | ||
|
|
5f8c4d31cc | ||
|
|
aa78f40843 | ||
|
|
721fb4cc4d | ||
|
|
f75a36f89f | ||
|
|
a375b9f774 | ||
|
|
16d029f10f | ||
|
|
bb45e09e8b | ||
|
|
2798088cec | ||
|
|
470703a490 | ||
|
|
c56d60b2d3 | ||
|
|
1178c3b6f1 | ||
|
|
0db44ca55b | ||
|
|
ae5015424b | ||
|
|
32c7a7ff1d | ||
|
|
39e601cbd4 | ||
|
|
ce9c896371 | ||
|
|
0008cb20dd | ||
|
|
701242ed25 | ||
|
|
67dd4bfca7 | ||
|
|
88fb4cafbc | ||
|
|
feb410ddc3 | ||
|
|
43a8dd1303 | ||
|
|
188f6b33e0 | ||
|
|
27e4eb3685 | ||
|
|
cd8294eca0 | ||
|
|
e12ecf831e | ||
|
|
1213182012 | ||
|
|
d5df71619a | ||
|
|
a177884893 | ||
|
|
1f7d8a7bb7 | ||
|
|
dc02d2722a | ||
|
|
13ac9166ef | ||
|
|
3d6f360cb6 | ||
|
|
6659e77bd0 | ||
|
|
b061cc55ce | ||
|
|
b17db16c15 | ||
|
|
d36866301f | ||
|
|
ffccb65d1b | ||
|
|
af165342ed | ||
|
|
ed62236d31 | ||
|
|
346bdd9c16 | ||
|
|
dc41a0fd0c | ||
|
|
2b26a4e68a | ||
|
|
fa96b2b24d | ||
|
|
36f00adc7a | ||
|
|
5314a752bd | ||
|
|
0f6683f31e | ||
|
|
8ee96c36c9 | ||
|
|
89789900f5 | ||
|
|
6add44ae27 | ||
|
|
14a0c2d272 | ||
|
|
9e769c85cb | ||
|
|
d6e1008c7a | ||
|
|
0a4c10d6cc | ||
|
|
edfd2883f5 | ||
|
|
f6ac6f791e | ||
|
|
88fe15a985 | ||
|
|
a9f47c9e1e | ||
|
|
f17314a2d3 | ||
|
|
29739ebd13 | ||
|
|
3caba52dba | ||
|
|
44bcc50815 | ||
|
|
942d7c15b4 | ||
|
|
25be7aef1a | ||
|
|
a2e1ffe089 | ||
|
|
911f8eaa4c | ||
|
|
590ee6d514 | ||
|
|
5054a71062 | ||
|
|
d69c1c3176 |
2
.github/workflows/build-dev.yml
vendored
2
.github/workflows/build-dev.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: [ 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', 'sonicfi_rap750w-311a', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655', 'emplus_wap588m' ]
|
||||
target: [ 'cig_wf189h', 'cig_wf189w', 'cig_wf660a', 'cig_wf672', 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', 'sonicfi_rap750e-s', 'sonicfi_rap750w-311a', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655', 'emplus_wap588m', 'zyxel_nwa130be', 'sercomm_ap72tip-v4' ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
||||
@@ -117,8 +117,6 @@ hostapd_common_add_device_config() {
|
||||
config_add_boolean legacy_rates
|
||||
config_add_int cell_density
|
||||
config_add_int rts_threshold
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
config_add_int maxassoc
|
||||
config_add_boolean maxassoc_ignore_probe
|
||||
|
||||
@@ -162,7 +160,7 @@ hostapd_prepare_device_config() {
|
||||
|
||||
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
|
||||
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
|
||||
rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
|
||||
rts_threshold beacon_rate maxassoc \
|
||||
multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \
|
||||
maxassoc_ignore_probe band
|
||||
|
||||
@@ -261,8 +259,6 @@ hostapd_prepare_device_config() {
|
||||
hostapd_add_rate brlist "$br"
|
||||
done
|
||||
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
|
||||
[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
|
||||
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
|
||||
@@ -471,6 +467,9 @@ hostapd_common_add_bss_config() {
|
||||
config_add_string uci_section
|
||||
|
||||
config_add_boolean dynamic_probe_resp
|
||||
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
}
|
||||
|
||||
hostapd_set_vlan_file() {
|
||||
@@ -724,7 +723,8 @@ hostapd_set_bss_options() {
|
||||
airtime_bss_weight airtime_bss_limit airtime_sta_weight \
|
||||
multicast_to_unicast_all proxy_arp per_sta_vif \
|
||||
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
|
||||
vendor_elements fils uci_section dynamic_probe_resp
|
||||
vendor_elements fils uci_section dynamic_probe_resp \
|
||||
rssi_reject_assoc_rssi rssi_ignore_probe_request
|
||||
|
||||
set_default fils 0
|
||||
set_default isolate 0
|
||||
@@ -778,6 +778,8 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
|
||||
append bss_conf "utf8_ssid=$utf8_ssid" "$N"
|
||||
append bss_conf "multi_ap=$multi_ap" "$N"
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append bss_conf "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append bss_conf "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
|
||||
|
||||
[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
|
||||
|
||||
14
feeds/hostapd/hostapd/patches/zzz-ignore-probe-event.patch
Normal file
14
feeds/hostapd/hostapd/patches/zzz-ignore-probe-event.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -934,8 +934,10 @@ void handle_probe_req(struct hostapd_dat
|
||||
int ubus_response;
|
||||
|
||||
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
|
||||
- ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
||||
+ ssi_signal < hapd->iconf->rssi_ignore_probe_request) {
|
||||
+ hostapd_ubus_notify_rssi(hapd, "rssi-ignore-probe", mgmt->sa, ssi_signal);
|
||||
return;
|
||||
+ }
|
||||
|
||||
if (len < IEEE80211_HDRLEN)
|
||||
return;
|
||||
@@ -1944,6 +1944,21 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
return;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "address", addr);
|
||||
blobmsg_add_u32(&b, "rssi", rssi);
|
||||
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
|
||||
@@ -56,6 +56,7 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
|
||||
size_t len);
|
||||
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
|
||||
int chan_width, int cf1, int cf2);
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi);
|
||||
|
||||
void hostapd_ubus_notify_bss_transition_response(
|
||||
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
|
||||
|
||||
@@ -41,6 +41,8 @@ ALLWIFIBOARDS:= \
|
||||
edgecore-oap102 \
|
||||
edgecore-oap103 \
|
||||
edgecore-eap104 \
|
||||
emplus-wap385c \
|
||||
emplus-wap386v2 \
|
||||
liteon-wpx8324 \
|
||||
indio-um-310ax-v1 \
|
||||
indio-um-510axp-v1 \
|
||||
@@ -404,6 +406,8 @@ $(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102))
|
||||
$(eval $(call generate-ath11k-wifi-package,edgecore-oap102,Edgecore OAP102))
|
||||
$(eval $(call generate-ath11k-wifi-package,edgecore-oap103,Edgecore OAP103))
|
||||
$(eval $(call generate-ath11k-wifi-package,edgecore-eap104,Edgecore EAP104))
|
||||
$(eval $(call generate-ath11k-wifi-package,emplus-wap385c,Emplus WAP385C))
|
||||
$(eval $(call generate-ath11k-wifi-package,emplus-wap386v2,Emplus WAP386 V2))
|
||||
$(eval $(call generate-ath11k-wifi-package,liteon-wpx8324,Liteon WPX8324))
|
||||
$(eval $(call generate-ath11k-wifi-package,indio-um-310ax-v1,Indio UM-310AX V1))
|
||||
$(eval $(call generate-ath11k-wifi-package,indio-um-510axp-v1,Indio UM-510AXP V1))
|
||||
|
||||
BIN
feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.IPQ5018
Normal file
BIN
feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.IPQ5018
Normal file
Binary file not shown.
BIN
feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.QCN6122
Normal file
BIN
feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.QCN6122
Normal file
Binary file not shown.
Binary file not shown.
@@ -18,9 +18,11 @@ start() {
|
||||
[ "$enabled" -gt 0 ] || return 1
|
||||
|
||||
case "$board" in
|
||||
sonicfi,rap630c-311g|\
|
||||
sonicfi,rap630w-311g)
|
||||
service_start /usr/sbin/cooling
|
||||
sonicfi,rap630c-311g)
|
||||
service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630c-311g-cooling.conf
|
||||
;;
|
||||
sonicfi,rap630w-311g)
|
||||
service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630w-311g-cooling.conf
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -28,143 +28,270 @@
|
||||
|
||||
#define CUR_STATE_PATH "/sys/devices/virtual/thermal/cooling_device%i/cur_state"
|
||||
#define TEMPER_PATH "/sys/devices/virtual/thermal/thermal_zone%i/temp"
|
||||
#define CPU_FREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/%s"
|
||||
|
||||
#define PATH_MAX 256
|
||||
#define BUF_MAX 8
|
||||
#define THERSHOLD_MAX 20
|
||||
#define BUF_MAX 32
|
||||
#define PHY0 0
|
||||
#define PHY1 1
|
||||
#define NUM_VALUES 4
|
||||
|
||||
int load_config_file=0;
|
||||
|
||||
//#define ULOG_INFO(fmt, ...) ulog(LOG_INFO, fmt, ## __VA_ARGS__)
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned long u32;
|
||||
|
||||
u8 w2g_threshold_level=0;
|
||||
u8 w5g_threshold_level=0;
|
||||
u8 w2g_cur_temper=0;
|
||||
u8 w5g_cur_temper=0;
|
||||
u32 level_cpu_freq=1008000;
|
||||
|
||||
|
||||
/* default value of wifi thresholds*/
|
||||
#ifdef PLATFORM_RAP630C_311G
|
||||
u8 level_2g_lo[4]={0, 105, 110, 115};
|
||||
u8 level_2g_hi[4]={105, 110, 115, 120};
|
||||
u8 level_2g_limit[4]={0, 35, 50, 70};
|
||||
u8 level_5g_lo[4]={0, 105, 110, 115};
|
||||
u8 level_5g_hi[4]={105, 110, 115, 120};
|
||||
u8 level_5g_limit[4]={0, 20, 30, 50};
|
||||
u8 level_2g_high[4]={105, 110, 115, 120};
|
||||
u8 level_2g_low[4]={0, 105, 110, 115};
|
||||
u8 level_2g_mitigation[4]={0, 35, 50, 70};
|
||||
u8 level_5g_high[4]={105, 110, 115, 120};
|
||||
u8 level_5g_low[4]={0, 105, 110, 115};
|
||||
u8 level_5g_mitigation[4]={0, 20, 30, 50};
|
||||
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_RAP630W_311G
|
||||
u8 level_2g_lo[4]={0, 105, 110, 115};
|
||||
u8 level_2g_hi[4]={105, 110, 115, 120};
|
||||
u8 level_2g_limit[4]={0, 20, 50, 70};
|
||||
u8 level_5g_lo[4]={0, 105, 110, 115};
|
||||
u8 level_5g_hi[4]={105, 110, 115, 120};
|
||||
u8 level_5g_limit[4]={0, 20, 50, 70};
|
||||
u8 level_2g_high[4]={105, 110, 115, 120};
|
||||
u8 level_2g_low[4]={0, 105, 110, 115};
|
||||
u8 level_2g_mitigation[4]={0, 20, 50, 70};
|
||||
u8 level_5g_high[4]={105, 110, 115, 120};
|
||||
u8 level_5g_low[4]={0, 105, 110, 115};
|
||||
u8 level_5g_mitigation[4]={0, 20, 50, 70};
|
||||
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
|
||||
#endif
|
||||
|
||||
static char *config_file = NULL;
|
||||
char temp[4][BUF_MAX];
|
||||
|
||||
#define ULOG_DBG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__)
|
||||
typedef struct {
|
||||
int thresholds_high[NUM_VALUES];
|
||||
int thresholds_low[NUM_VALUES];
|
||||
int mitigation[NUM_VALUES];
|
||||
int cpu_freq[NUM_VALUES];
|
||||
} WifiConfig;
|
||||
|
||||
static void write_cur_state (char *filename, int state) {
|
||||
WifiConfig wifi2g = {0}, wifi5g = {0};
|
||||
|
||||
static void set_cpu_freq (int freq) {
|
||||
FILE * fp;
|
||||
char filename[PATH_MAX];
|
||||
|
||||
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_governor");
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (!fp) {
|
||||
ULOG_ERR("open scaling_governor error\n");
|
||||
}
|
||||
fprintf(fp, "%s", "userspace");
|
||||
fclose(fp);
|
||||
|
||||
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_setspeed");
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (!fp) {
|
||||
ULOG_ERR("open scaling_setspeed error\n");
|
||||
}
|
||||
fprintf(fp, "%d", freq);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void parse_line(const char* line, const char* key, int* array) {
|
||||
char label[64];
|
||||
int values[NUM_VALUES];
|
||||
int i;
|
||||
|
||||
if (sscanf(line, "%s %d %d %d %d %d", label, &values[0], &values[1], &values[2], &values[3], &values[4]) == 5) {
|
||||
for (i = 0; i < NUM_VALUES; ++i) {
|
||||
array[i] = values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int load_config() {
|
||||
FILE * fp = fopen(config_file, "r");
|
||||
if (!fp) {
|
||||
ULOG_ERR("open config file error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
WifiConfig* current_config = NULL;
|
||||
char line[256];
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (strstr(line, "[wifi2g]")) {
|
||||
current_config = &wifi2g;
|
||||
} else if (strstr(line, "[wifi5g]")) {
|
||||
current_config = &wifi5g;
|
||||
} else if (current_config) {
|
||||
if (strstr(line, "thresholds_high")) {
|
||||
parse_line(line, "thresholds_high", current_config->thresholds_high);
|
||||
} else if (strstr(line, "thresholds_low")) {
|
||||
parse_line(line, "thresholds_low", current_config->thresholds_low);
|
||||
} else if (strstr(line, "mitigation")) {
|
||||
parse_line(line, "mitigation", current_config->mitigation);
|
||||
} else if (strstr(line, "CPU_freq")) {
|
||||
parse_line(line, "CPU_freq", current_config->cpu_freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
set_cpu_freq(wifi5g.cpu_freq[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_default_config(){
|
||||
int i=0;
|
||||
|
||||
set_cpu_freq(1008000);
|
||||
for (i = 0; i < NUM_VALUES; i++) {
|
||||
wifi2g.thresholds_high[i]=level_2g_high[i];
|
||||
wifi2g.thresholds_low[i]=level_2g_low[i];
|
||||
wifi2g.mitigation[i]=level_2g_mitigation[i];
|
||||
wifi2g.cpu_freq[i]=level_cpu_frequency[i];
|
||||
wifi5g.thresholds_high[i]=level_5g_high[i];
|
||||
wifi5g.thresholds_low[i]=level_5g_low[i];
|
||||
wifi5g.mitigation[i]=level_5g_mitigation[i];
|
||||
wifi5g.cpu_freq[i]=level_cpu_frequency[i];
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void write_cur_state (const char *filename, int state) {
|
||||
FILE * fp;
|
||||
|
||||
ULOG_DBG("write_cur_state filename=[%s] [%d]\n", filename, state);
|
||||
fp = fopen(filename, "w");
|
||||
if (!fp){
|
||||
ULOG_ERR("some kind of error write cur_state\n");
|
||||
ULOG_ERR("open %s file error\n",filename);
|
||||
}
|
||||
fprintf(fp, "%d", state);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void read_cur_state (char *filename, char *buffer) {
|
||||
FILE * fp;
|
||||
|
||||
int read_cur_state(const char *filename, char *buf, size_t buffer) {
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp){
|
||||
ULOG_ERR("some kind of error write cur_state\n");
|
||||
if (!fp) {
|
||||
ULOG_ERR("open %s file error\n",filename);
|
||||
return -1;
|
||||
}
|
||||
if (0 == fread(buffer, sizeof(char), 3, fp)) {
|
||||
ULOG_ERR("some kind of error read value\n");
|
||||
if (!fgets(buf, buffer, fp)) {
|
||||
ULOG_ERR("Failed to read %s file\n", filename);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void wifi_get_temperature() {
|
||||
char filename[PATH_MAX];
|
||||
FILE * fp;
|
||||
int i = 0;
|
||||
char buffer[BUF_MAX];
|
||||
int i = 0;
|
||||
|
||||
// ULOG_INFO("=================================\n");
|
||||
|
||||
/* read cpuinfo_cur_freq*/
|
||||
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "cpuinfo_cur_freq");
|
||||
|
||||
memset(buffer, 0, BUF_MAX);
|
||||
read_cur_state(filename, buffer, sizeof(buffer));
|
||||
// ULOG_INFO("CPU current frequency: %s\n", buffer);
|
||||
|
||||
/* get current phy cooling state*/
|
||||
for (i=0 ; i <= 1; i++ ) {
|
||||
for (i=0; i <= 1; i++) {
|
||||
memset(buffer, 0, BUF_MAX);
|
||||
snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
|
||||
read_cur_state(filename, buffer);
|
||||
ULOG_DBG("read from Phy%i cur_state is %s\n", i, buffer);
|
||||
read_cur_state(filename, buffer, sizeof(buffer));
|
||||
// ULOG_INFO("Phy%i cur_state is: %s\n", i, buffer);
|
||||
}
|
||||
|
||||
for (i=0 ; i <= 3; i++ ) {
|
||||
for (i=0; i <= 3; i++) {
|
||||
memset(buffer, 0, BUF_MAX);
|
||||
snprintf(filename, PATH_MAX, TEMPER_PATH, i);
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
ULOG_ERR("some kind of error open value\n");
|
||||
}
|
||||
memset(temp[i], 0, BUF_MAX);
|
||||
if (0 == fread(temp[i], sizeof(char), 3, fp)) {
|
||||
ULOG_ERR("some kind of error read value\n");
|
||||
}
|
||||
fclose(fp);
|
||||
ULOG_DBG("thermal_zone%i cur_temp is %s\n", i, temp[i]);
|
||||
read_cur_state(filename, buffer, sizeof(buffer));
|
||||
// ULOG_INFO("thermal_zone%i cur_temp is: %s\n", i, buffer);
|
||||
|
||||
if (i == 0)
|
||||
w2g_cur_temper=atoi(buffer);
|
||||
else if (i == 3)
|
||||
w5g_cur_temper=atoi(buffer);
|
||||
}
|
||||
|
||||
w2g_cur_temper=atoi(temp[0]);
|
||||
w5g_cur_temper=atoi(temp[3]);
|
||||
if (w5g_cur_temper >= 120)
|
||||
{
|
||||
ULOG_ERR("!! Temperature is over %d degree, system will reboot\n", w5g_cur_temper);
|
||||
sync();
|
||||
if ( -1 != system("reboot &") ){
|
||||
printf("sysyem reboot...\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_set_cooling() {
|
||||
char filename[PATH_MAX];
|
||||
int level;
|
||||
|
||||
for (level=0 ; level<=3 ; level++) {
|
||||
if (w2g_cur_temper >= level_2g_lo[level] && w2g_cur_temper < level_2g_hi[level]) {
|
||||
ULOG_DBG("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
|
||||
for (level = 0; level <= 3; level++) {
|
||||
if (w2g_cur_temper >= wifi2g.thresholds_low[level] && w2g_cur_temper < wifi2g.thresholds_high[level]) {
|
||||
// ULOG_INFO("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
|
||||
if (w2g_threshold_level != level) {
|
||||
ULOG_DBG("setting 2G reduce %d percent\n" ,level_2g_limit[level]);
|
||||
// ULOG_INFO("setting 2G reduce %d percent\n" ,wifi2g.mitigation[level]);
|
||||
snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY0);
|
||||
write_cur_state(filename, level_2g_limit[level]);
|
||||
write_cur_state(filename, wifi2g.mitigation[level]);
|
||||
w2g_threshold_level = level;
|
||||
}
|
||||
}
|
||||
if (w5g_cur_temper >= level_5g_lo[level] && w5g_cur_temper < level_5g_hi[level]) {
|
||||
ULOG_DBG("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
|
||||
if (w5g_cur_temper >= wifi5g.thresholds_low[level] && w5g_cur_temper < wifi5g.thresholds_high[level]) {
|
||||
// ULOG_INFO("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
|
||||
if (w5g_threshold_level != level) {
|
||||
ULOG_DBG("setting 5G reduce %d percent\n" ,level_5g_limit[level]);
|
||||
// ULOG_INFO("setting 5G reduce %d percent\n" ,wifi5g.mitigation[level]);
|
||||
snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY1);
|
||||
write_cur_state(filename, level_5g_limit[level]);
|
||||
write_cur_state(filename, wifi5g.mitigation[level]);
|
||||
w5g_threshold_level = level;
|
||||
set_cpu_freq(wifi5g.cpu_freq[level]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void cooling_init() {
|
||||
char filename[256];
|
||||
int i;
|
||||
char filename[PATH_MAX];
|
||||
int i,result=0;
|
||||
|
||||
for (i=0 ; i <= 1; i++) {
|
||||
snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
|
||||
write_cur_state(filename, 0);
|
||||
}
|
||||
|
||||
if(load_config_file)
|
||||
result = load_config();
|
||||
|
||||
if (result == 1 || load_config_file == 0)
|
||||
load_default_config();
|
||||
}
|
||||
|
||||
void print_usage(void)
|
||||
{
|
||||
printf("\nWifi-cooling daemon usage\n");
|
||||
printf("Optional arguments:\n");
|
||||
printf(" -c <file> config file\n");
|
||||
printf(" -d debug output\n");
|
||||
printf(" -c <file> setting with config file\n");
|
||||
printf(" -d default setting\n");
|
||||
printf(" -h this usage screen\n");
|
||||
}
|
||||
|
||||
@@ -185,17 +312,18 @@ int main(int argc, char *argv[])
|
||||
setpriority(PRIO_PROCESS, getpid(), -20);
|
||||
|
||||
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "cooling");
|
||||
ulog_threshold(LOG_INFO);
|
||||
ulog_threshold(LOG_ERR);
|
||||
// ulog_threshold(LOG_INFO);
|
||||
|
||||
while ((ch = getopt(argc, argv, "c:dh")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "c:dh")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
printf("wifi-cooling load configuration file %s\n", optarg);
|
||||
config_file = optarg;
|
||||
load_config_file=1;
|
||||
break;
|
||||
case 'd':
|
||||
printf("wifi-cooling ulog_threshold set to debug level\n");
|
||||
ulog_threshold(LOG_DEBUG);
|
||||
printf("wifi-cooling set to default value\n");
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
@@ -212,4 +340,4 @@ int main(int argc, char *argv[])
|
||||
uloop_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
sampling 5000
|
||||
[wifi2g]
|
||||
thresholds_high 105 110 115 120
|
||||
thresholds_low 0 105 110 115
|
||||
mitigation 0 35 50 70
|
||||
CPU_freq 1008000 800000 800000 800000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 5000
|
||||
thresholds 105 110 115 119 120
|
||||
thresholds_clr 0 100 105 110 115
|
||||
actions cooling cooling cooling cooling shutdown
|
||||
action_info 0 35 50 70 800000
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 5000
|
||||
thresholds 105 110 115 119 120
|
||||
thresholds_clr 0 100 105 110 115
|
||||
actions cooling cooling cooling cooling shutdown
|
||||
action_info 0 20 30 50 800000
|
||||
[wifi5g]
|
||||
thresholds_high 105 110 115 120
|
||||
thresholds_low 0 105 110 115
|
||||
mitigation 0 20 30 50
|
||||
CPU_freq 1008000 800000 800000 800000
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
sampling 5000
|
||||
[wifi2g]
|
||||
thresholds_high 105 110 115 120
|
||||
thresholds_low 0 105 110 115
|
||||
mitigation 0 20 50 70
|
||||
CPU_freq 1008000 800000 800000 800000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 5000
|
||||
thresholds 105 115 119 125
|
||||
thresholds_clr 0 105 110 120
|
||||
actions cooling cooling cooling cooling
|
||||
action_info 0 20 50 70
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 5000
|
||||
thresholds 105 115 119 125
|
||||
thresholds_clr 0 105 110 120
|
||||
actions cooling cooling cooling cooling
|
||||
action_info 0 20 50 70
|
||||
[wifi5g]
|
||||
thresholds_high 105 110 115 120
|
||||
thresholds_low 0 105 110 115
|
||||
mitigation 0 20 50 70
|
||||
CPU_freq 1008000 800000 800000 800000
|
||||
|
||||
@@ -117,8 +117,6 @@ hostapd_common_add_device_config() {
|
||||
config_add_boolean legacy_rates
|
||||
config_add_int cell_density
|
||||
config_add_int rts_threshold
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
config_add_int maxassoc
|
||||
config_add_boolean maxassoc_ignore_probe
|
||||
|
||||
@@ -162,7 +160,7 @@ hostapd_prepare_device_config() {
|
||||
|
||||
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
|
||||
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
|
||||
rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
|
||||
rts_threshold beacon_rate maxassoc \
|
||||
multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \
|
||||
maxassoc_ignore_probe band
|
||||
|
||||
@@ -261,8 +259,6 @@ hostapd_prepare_device_config() {
|
||||
hostapd_add_rate brlist "$br"
|
||||
done
|
||||
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
|
||||
[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
|
||||
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
|
||||
@@ -472,6 +468,9 @@ hostapd_common_add_bss_config() {
|
||||
config_add_string uci_section
|
||||
|
||||
config_add_boolean dynamic_probe_resp
|
||||
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
}
|
||||
|
||||
hostapd_set_vlan_file() {
|
||||
@@ -725,7 +724,8 @@ hostapd_set_bss_options() {
|
||||
airtime_bss_weight airtime_bss_limit airtime_sta_weight \
|
||||
multicast_to_unicast_all proxy_arp per_sta_vif \
|
||||
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
|
||||
vendor_elements fils uci_section dynamic_probe_resp multi_psk
|
||||
vendor_elements fils uci_section dynamic_probe_resp multi_psk \
|
||||
rssi_reject_assoc_rssi rssi_ignore_probe_request
|
||||
|
||||
set_default fils 0
|
||||
set_default isolate 0
|
||||
@@ -780,6 +780,8 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
|
||||
append bss_conf "utf8_ssid=$utf8_ssid" "$N"
|
||||
append bss_conf "multi_ap=$multi_ap" "$N"
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append bss_conf "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append bss_conf "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
|
||||
|
||||
[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
|
||||
|
||||
@@ -144,7 +144,7 @@ function netifd_reload() {
|
||||
|
||||
push(ssid.interfaces, iface.ifname);
|
||||
ssid.bands[band] = iface.ifname;
|
||||
ssid.mpsk = config.multi_psk;
|
||||
ssid.mpsk = ssid?.mpsk ? true : config.multi_psk;
|
||||
for (let sta in iface.stations) {
|
||||
let stacfg = sta.config;
|
||||
|
||||
@@ -308,18 +308,18 @@ function sta_auth_cache(ifname, addr, idx, phrase) {
|
||||
function auth_cb(msg) {
|
||||
let data = msg.data;
|
||||
|
||||
if (!is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
|
||||
printf(`Event ${msg.type}: ${msg.data}\n`);
|
||||
switch (msg.type) {
|
||||
case 'sta_auth':
|
||||
if (!is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
|
||||
return {
|
||||
psk: sta_auth_psk(data.iface, data.sta),
|
||||
force_psk: true,
|
||||
};
|
||||
case 'sta_connected':
|
||||
if (data.psk_idx == null)
|
||||
if (data.psk_idx == null || !is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
return sta_auth_cache(data.iface, data.sta, data.psk_idx, data.psk);
|
||||
case 'reload':
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -934,8 +934,10 @@ void handle_probe_req(struct hostapd_dat
|
||||
int ubus_response;
|
||||
|
||||
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
|
||||
- ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
||||
+ ssi_signal < hapd->iconf->rssi_ignore_probe_request) {
|
||||
+ hostapd_ubus_notify_rssi(hapd, "rssi-ignore-probe", mgmt->sa, ssi_signal);
|
||||
return;
|
||||
+ }
|
||||
|
||||
if (len < IEEE80211_HDRLEN)
|
||||
return;
|
||||
@@ -1944,6 +1944,21 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
return;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "address", addr);
|
||||
blobmsg_add_u32(&b, "rssi", rssi);
|
||||
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
|
||||
@@ -56,6 +56,7 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
|
||||
size_t len);
|
||||
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
|
||||
int chan_width, int cf1, int cf2);
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi);
|
||||
|
||||
void hostapd_ubus_notify_bss_transition_response(
|
||||
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
|
||||
|
||||
@@ -40,6 +40,11 @@ edgecore,oap101e-6e)
|
||||
ucidef_set_led_netdev "wan" "wan" "red:ethernet" "eth1"
|
||||
ucidef_set_led_default "power" "POWER" "blue:management" "on"
|
||||
;;
|
||||
emplus,wap385c)
|
||||
ucidef_set_led_default "ledr" "LEDR" "sys:red" "on"
|
||||
ucidef_set_led_default "ledg" "LEDG" "sys:green" "on"
|
||||
ucidef_set_led_default "ledb" "LEDB" "sys:blue" "on"
|
||||
;;
|
||||
hfcl,ion4x_w|\
|
||||
hfcl,ion4xi_w)
|
||||
ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
|
||||
|
||||
@@ -48,6 +48,7 @@ qcom_setup_interfaces()
|
||||
ucidef_add_switch "switch1" \
|
||||
"6u@eth1" "1:lan" "2:lan" "3:lan" "4:lan"
|
||||
;;
|
||||
emplus,wap385c|\
|
||||
hfcl,ion4x_w|\
|
||||
hfcl,ion4xi_w)
|
||||
ucidef_set_interface_wan "eth0"
|
||||
|
||||
@@ -129,6 +129,7 @@ ath11k/IPQ5018/hw1.0/caldata.bin)
|
||||
edgecore,oap101-6e|\
|
||||
edgecore,oap101e|\
|
||||
edgecore,oap101e-6e|\
|
||||
emplus,wap385c|\
|
||||
hfcl,ion4x_w|\
|
||||
hfcl,ion4xi_w|\
|
||||
optimcloud,d60|\
|
||||
@@ -157,6 +158,7 @@ ath11k/qcn6122/hw1.0/caldata_1.bin)
|
||||
edgecore,oap101-6e|\
|
||||
edgecore,oap101e|\
|
||||
edgecore,oap101e-6e|\
|
||||
emplus,wap385c|\
|
||||
udaya,a6-id2|\
|
||||
udaya,a6-od2|\
|
||||
hfcl,ion4xi_w|\
|
||||
|
||||
@@ -76,6 +76,7 @@ platform_check_image() {
|
||||
cybertan,eww631-a1|\
|
||||
cybertan,eww631-b1|\
|
||||
edgecore,eap104|\
|
||||
emplus,wap385c|\
|
||||
wallys,dr5018|\
|
||||
hfcl,ion4x_w|\
|
||||
hfcl,ion4xi_w|\
|
||||
@@ -129,6 +130,7 @@ platform_do_upgrade() {
|
||||
;;
|
||||
cig,wf186w|\
|
||||
cig,wf186h|\
|
||||
emplus,wap385c|\
|
||||
udaya,a6-id2|\
|
||||
udaya,a6-od2|\
|
||||
wallys,dr5018|\
|
||||
|
||||
@@ -0,0 +1,760 @@
|
||||
/dts-v1/;
|
||||
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ipq5018.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <0x2>;
|
||||
#size-cells = <0x2>;
|
||||
model = "Emplus WAP385C";
|
||||
compatible = "emplus,wap385c", "qcom,ipq5018-mp03.3", "qcom,ipq5018";
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
aliases {
|
||||
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
|
||||
serial0 = &blsp1_uart1;
|
||||
serial1 = &blsp1_uart2;
|
||||
ethernet1 = "/soc/dp1";
|
||||
|
||||
led-boot = &led_power;
|
||||
led-failsafe = &led_power;
|
||||
led-running = &led_power;
|
||||
led-upgrade = &led_power;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
|
||||
bootargs-append = " swiotlb=1 coherent_pool=2M";
|
||||
stdout-path = "serial0";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
/* 256 MB Profile
|
||||
* +==========+==============+=========================+
|
||||
* | | | |
|
||||
* | Region | Start Offset | Size |
|
||||
* | | | |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | NSS | 0x40000000 | 8MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | Linux | 0x40800000 | Depends on total memory |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | uboot | 0x4A600000 | 4MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | SBL | 0x4AA00000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | smem | 0x4AB00000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | TZ | 0x4AC00000 | 4MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | Q6 | | |
|
||||
* | code/ | 0x4B000000 | 20MB |
|
||||
* | data | | |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | data | 0x4C400000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | M3 Dump | 0x4D100000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | QDSS | 0x4D200000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | data | 0x4D300000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | M3 Dump | 0x4E000000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | QDSS | 0x4E100000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | data | 0x4E200000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | M3 Dump | 0x4EF00000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | QDSS | 0x4F000000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | |
|
||||
* | Rest of the memory for Linux |
|
||||
* | |
|
||||
* +===================================================+
|
||||
*/
|
||||
q6_mem_regions: q6_mem_regions@4B000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4B000000 0x0 0x4100000>;
|
||||
};
|
||||
|
||||
q6_code_data: q6_code_data@4B000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4B000000 0x0 0x1400000>;
|
||||
};
|
||||
|
||||
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4C400000 0x0 0xD00000>;
|
||||
};
|
||||
|
||||
m3_dump: m3_dump@4D100000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D100000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_etr_region: q6_etr_dump@4D200000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D200000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D300000 0x0 0xD00000>;
|
||||
};
|
||||
|
||||
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E000000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E100000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E100000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_data2: q6_qcn6122_data2@4E200000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E200000 0x0 0xD00000>;
|
||||
};
|
||||
|
||||
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4EF00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4EF00000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4F000000 0x0 0x100000>;
|
||||
};
|
||||
#else
|
||||
/* 512MB/1GB Profiles
|
||||
* +==========+==============+=========================+
|
||||
* | | | |
|
||||
* | Region | Start Offset | Size |
|
||||
* | | | |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | NSS | 0x40000000 | 16MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | Linux | 0x41000000 | Depends on total memory |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | uboot | 0x4A600000 | 4MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | SBL | 0x4AA00000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | smem | 0x4AB00000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | TZ | 0x4AC00000 | 4MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | Q6 | | |
|
||||
* | code/ | 0x4B000000 | 20MB |
|
||||
* | data | | |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | data | 0x4C400000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | M3 Dump | 0x4D100000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | QDSS | 0x4D200000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | IPQ5018 | | |
|
||||
* | Caldb | 0x4D300000 | 2MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | data | 0x4D500000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | M3 Dump | 0x4E200000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | QDSS | 0x4E300000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_1| | |
|
||||
* | Caldb | 0x4E400000 | 5MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | data | 0x4E900000 | 13MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | M3 Dump | 0x4F600000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | QDSS | 0x4F700000 | 1MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | QCN6122_2| | |
|
||||
* | Caldb | 0x4F800000 | 5MB |
|
||||
* +----------+--------------+-------------------------+
|
||||
* | |
|
||||
* | Rest of the memory for Linux |
|
||||
* | |
|
||||
* +===================================================+
|
||||
*/
|
||||
q6_mem_regions: q6_mem_regions@4B000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4B000000 0x0 0x4D00000>;
|
||||
};
|
||||
|
||||
q6_code_data: q6_code_data@4B000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4B000000 0x0 01400000>;
|
||||
};
|
||||
|
||||
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4C400000 0x0 0xD00000>;
|
||||
};
|
||||
|
||||
m3_dump: m3_dump@4D100000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D100000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_etr_region: q6_etr_dump@4D200000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D200000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_caldb_region: q6_caldb_region@4D300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D300000 0x0 0x200000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_data1: q6_qcn6122_data1@4D500000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D500000 0x0 0xD00000>;
|
||||
};
|
||||
|
||||
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E200000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E300000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E400000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E400000 0x0 0x500000>;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
soc {
|
||||
serial@78af000 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
qpic_bam: dma@7984000{
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
nand: qpic-nand@79b0000 {
|
||||
pinctrl-0 = <&qspi_nand_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
spi_0: spi@78b5000 { /* BLSP1 QUP0 */
|
||||
pinctrl-0 = <&blsp0_spi_pins>;
|
||||
pinctrl-names = "default";
|
||||
cs-select = <0>;
|
||||
status = "ok";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0>;
|
||||
compatible = "n25q128a11";
|
||||
linux,modalias = "m25p80", "n25q128a11";
|
||||
spi-max-frequency = <50000000>;
|
||||
use-default-sizes;
|
||||
};
|
||||
};
|
||||
|
||||
mdio0: mdio@88000 {
|
||||
status = "ok";
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <7>;
|
||||
};
|
||||
};
|
||||
|
||||
mdio1: mdio@90000 {
|
||||
status = "ok";
|
||||
pinctrl-0 = <&mdio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
phy-reset-gpio = <&tlmm 23 0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <24>;
|
||||
};
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x1>;
|
||||
ess-switch@0x39c00000 {
|
||||
switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
|
||||
cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
|
||||
qcom,port_phyinfo {
|
||||
port@0 {
|
||||
port_id = <1>;
|
||||
phy_address = <7>;
|
||||
mdiobus = <&mdio0>;
|
||||
};
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
phy_address = <0x18>;
|
||||
mdiobus = <&mdio1>;
|
||||
port_mac_sel = "QGMAC_PORT";
|
||||
};
|
||||
};
|
||||
led_source@0 {
|
||||
source = <0>;
|
||||
mode = "normal";
|
||||
speed = "all";
|
||||
blink_en = "enable";
|
||||
active = "high";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
wifi0: wifi@c000000 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
|
||||
clock-names = "nss-snoc-gmac-axi-clk";
|
||||
qcom,id = <1>;
|
||||
reg = <0x39C00000 0x10000>;
|
||||
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
|
||||
qcom,mactype = <2>;
|
||||
qcom,link-poll = <1>;
|
||||
qcom,phy-mdio-addr = <7>;
|
||||
mdio-bus = <&mdio0>;
|
||||
local-mac-address = [000000000000];
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
nss-macsec1 {
|
||||
compatible = "qcom,nss-macsec";
|
||||
phy_addr = <0x18>;
|
||||
mdiobus = <&mdio1>;
|
||||
};
|
||||
|
||||
lpass: lpass@0xA000000{
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcm_lb: pcm_lb@0 {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
qcom,test@0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
status = "ok";
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
pinctrl-0 = <&blsp0_uart_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
blsp0_uart_pins: uart_pins {
|
||||
blsp0_uart_rx_tx {
|
||||
pins = "gpio20", "gpio21";
|
||||
function = "blsp0_uart0";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
blsp0_spi_pins: blsp0_spi_pins {
|
||||
mux {
|
||||
pins = "gpio10", "gpio11", "gpio12", "gpio13";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
qspi_nand_pins: qspi_nand_pins {
|
||||
qspi_clock {
|
||||
pins = "gpio9";
|
||||
function = "qspi_clk";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
qspi_cs {
|
||||
pins = "gpio8";
|
||||
function = "qspi_cs";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
qspi_data {
|
||||
pins = "gpio4", "gpio5", "gpio6", "gpio7";
|
||||
function = "qspi_data";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
mdio1_pins: mdio_pinmux {
|
||||
mux_0 {
|
||||
pins = "gpio36";
|
||||
function = "mdc";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
mux_1 {
|
||||
pins = "gpio37";
|
||||
function = "mdio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
poe_dc_pins: poe_dc_pins {
|
||||
T2P_DET {
|
||||
pins = "gpio31";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
12V_DET {
|
||||
pins = "gpio32";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
button_pins: button_pins {
|
||||
reset_button {
|
||||
pins = "gpio27";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
leds_pins: leds_pinmux {
|
||||
linux,phandle = <0x4d>;
|
||||
phandle = <0x4d>;
|
||||
|
||||
led_G {
|
||||
pins = "gpio24";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <0x08>;
|
||||
};
|
||||
|
||||
led_B {
|
||||
pins = "gpio28";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <0x08>;
|
||||
};
|
||||
|
||||
led_R {
|
||||
pins = "gpio38";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <0x08>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&soc {
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
button@1 {
|
||||
label = "reset";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
pinctrl-0 = <&leds_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
led@24 {
|
||||
label = "sys:green";
|
||||
gpios = <&tlmm 24 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@28 {
|
||||
label = "sys:blue";
|
||||
gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led_power: led@38 {
|
||||
label = "sys:red";
|
||||
gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "wap385c:sys:red";
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&q6v5_wcss {
|
||||
compatible = "qcom,ipq5018-q6-mpd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
firmware = "IPQ5018/q6_fw.mdt";
|
||||
reg = <0x0cd00000 0x4040>,
|
||||
<0x1938000 0x8>,
|
||||
<0x193d204 0x4>;
|
||||
reg-names = "qdsp6",
|
||||
"tcsr-msip",
|
||||
"tcsr-q6";
|
||||
resets = <&gcc GCC_WCSSAON_RESET>,
|
||||
<&gcc GCC_WCSS_Q6_BCR>;
|
||||
|
||||
reset-names = "wcss_aon_reset",
|
||||
"wcss_q6_reset";
|
||||
|
||||
clocks = <&gcc GCC_Q6_AXIS_CLK>,
|
||||
<&gcc GCC_WCSS_ECAHB_CLK>,
|
||||
<&gcc GCC_Q6_AXIM_CLK>,
|
||||
<&gcc GCC_Q6_AXIM2_CLK>,
|
||||
<&gcc GCC_Q6_AHB_CLK>,
|
||||
<&gcc GCC_Q6_AHB_S_CLK>,
|
||||
<&gcc GCC_WCSS_AXI_S_CLK>;
|
||||
clock-names = "gcc_q6_axis_clk",
|
||||
"gcc_wcss_ecahb_clk",
|
||||
"gcc_q6_axim_clk",
|
||||
"gcc_q6_axim2_clk",
|
||||
"gcc_q6_ahb_clk",
|
||||
"gcc_q6_ahb_s_clk",
|
||||
"gcc_wcss_axi_s_clk";
|
||||
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
memory-region = <&q6_mem_regions>, <&q6_etr_region>;
|
||||
#else
|
||||
memory-region = <&q6_mem_regions>, <&q6_etr_region>,
|
||||
<&q6_caldb_region>;
|
||||
#endif
|
||||
|
||||
qcom,rproc = <&q6v5_wcss>;
|
||||
qcom,bootargs_smem = <507>;
|
||||
boot-args = <0x1 0x4 0x3 0x0F 0x0 0x0>,
|
||||
<0x2 0x4 0x2 0x12 0x0 0x0>;
|
||||
status = "ok";
|
||||
|
||||
q6_wcss_pd1: remoteproc_pd1@4ab000 {
|
||||
compatible = "qcom,ipq5018-wcss-ahb-mpd";
|
||||
reg = <0x4ab000 0x20>;
|
||||
reg-names = "rmb";
|
||||
firmware = "IPQ5018/q6_fw.mdt";
|
||||
m3_firmware = "IPQ5018/m3_fw.mdt";
|
||||
interrupts-extended = <&wcss_smp2p_in 8 0>,
|
||||
<&wcss_smp2p_in 9 0>,
|
||||
<&wcss_smp2p_in 12 0>,
|
||||
<&wcss_smp2p_in 11 0>;
|
||||
interrupt-names = "fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
|
||||
resets = <&gcc GCC_WCSSAON_RESET>,
|
||||
<&gcc GCC_WCSS_BCR>,
|
||||
<&gcc GCC_CE_BCR>;
|
||||
reset-names = "wcss_aon_reset",
|
||||
"wcss_reset",
|
||||
"ce_reset";
|
||||
|
||||
clocks = <&gcc GCC_WCSS_AHB_S_CLK>,
|
||||
<&gcc GCC_WCSS_ACMT_CLK>,
|
||||
<&gcc GCC_WCSS_AXI_M_CLK>;
|
||||
clock-names = "gcc_wcss_ahb_s_clk",
|
||||
"gcc_wcss_acmt_clk",
|
||||
"gcc_wcss_axi_m_clk";
|
||||
|
||||
qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
|
||||
|
||||
qcom,smem-states = <&wcss_smp2p_out 8>,
|
||||
<&wcss_smp2p_out 9>,
|
||||
<&wcss_smp2p_out 10>;
|
||||
qcom,smem-state-names = "shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
|
||||
<&q6_etr_region>;
|
||||
#else
|
||||
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
|
||||
<&q6_etr_region>, <&q6_caldb_region>;
|
||||
#endif
|
||||
};
|
||||
|
||||
q6_wcss_pd2: remoteproc_pd2 {
|
||||
compatible = "qcom,ipq5018-wcss-pcie-mpd";
|
||||
firmware = "IPQ5018/q6_fw.mdt";
|
||||
m3_firmware = "qcn6122/m3_fw.mdt";
|
||||
interrupts-extended = <&wcss_smp2p_in 16 0>,
|
||||
<&wcss_smp2p_in 17 0>,
|
||||
<&wcss_smp2p_in 20 0>,
|
||||
<&wcss_smp2p_in 19 0>;
|
||||
interrupt-names = "fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
qcom,smem-states = <&wcss_smp2p_out 16>,
|
||||
<&wcss_smp2p_out 17>,
|
||||
<&wcss_smp2p_out 18>;
|
||||
qcom,smem-state-names = "shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
|
||||
<&q6_qcn6122_etr_1>;
|
||||
#else
|
||||
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
|
||||
<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
|
||||
#endif
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
/* IPQ5018 */
|
||||
qcom,multipd_arch;
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
qcom,tgt-mem-mode = <2>;
|
||||
#else
|
||||
qcom,tgt-mem-mode = <1>;
|
||||
#endif
|
||||
qcom,board_id = <0x24>;
|
||||
#ifdef __CNSS2__
|
||||
qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
|
||||
qcom,caldb-addr = <0x4D300000 0x4D300000 0 0 0>;
|
||||
qcom,caldb-size = <0x200000>;
|
||||
mem-region = <&q6_ipq5018_data>;
|
||||
#else
|
||||
memory-region = <&q6_ipq5018_data>;
|
||||
#endif
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
/* QCN6122 5G */
|
||||
qcom,multipd_arch;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
|
||||
qcom,rproc = <&q6_wcss_pd2>;
|
||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
|
||||
qcom,tgt-mem-mode = <2>;
|
||||
#else
|
||||
qcom,tgt-mem-mode = <1>;
|
||||
#endif
|
||||
qcom,board_id = <0x60>;
|
||||
#ifdef __CNSS2__
|
||||
qcom,bdf-addr = <0x4D500000 0x4D500000 0x4D300000 0x0 0x0>;
|
||||
qcom,caldb-addr = <0x4E400000 0x4E400000 0 0 0>;
|
||||
qcom,caldb-size = <0x500000>;
|
||||
mem-region = <&q6_qcn6122_data1>;
|
||||
#else
|
||||
memory-region = <&q6_qcn6122_data1>;
|
||||
#endif
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&dwc_0 {
|
||||
/delete-property/ #phy-cells;
|
||||
/delete-property/ phys;
|
||||
/delete-property/ phy-names;
|
||||
};
|
||||
|
||||
&hs_m31phy_0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&eud {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&pcie_x1 {
|
||||
perst-gpio = <&tlmm 18 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&pcie_x2 {
|
||||
perst-gpio = <&tlmm 15 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&pcie_x1_rp {
|
||||
status = "disabled";
|
||||
|
||||
mhi_0: qcom,mhi@0 {
|
||||
reg = <0 0 0 0 0 >;
|
||||
};
|
||||
};
|
||||
|
||||
&pcie_x2_rp {
|
||||
status = "disabled";
|
||||
|
||||
mhi_1: qcom,mhi@1 {
|
||||
reg = <0 0 0 0 0 >;
|
||||
};
|
||||
};
|
||||
|
||||
&qfprom {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&tsens {
|
||||
status = "ok";
|
||||
};
|
||||
@@ -154,6 +154,15 @@ define Device/edgecore_oap101e_6e
|
||||
endef
|
||||
TARGET_DEVICES += edgecore_oap101e_6e
|
||||
|
||||
define Device/emplus_wap385c
|
||||
DEVICE_TITLE := Emplus WAP385C
|
||||
DEVICE_DTS := qcom-ipq5018-emplus-wap385c
|
||||
SUPPORTED_DEVICES := emplus,wap385c
|
||||
DEVICE_PACKAGES := ath11k-wifi-emplus-wap385c ath11k-firmware-ipq50xx-map-spruce
|
||||
DEVICE_DTS_CONFIG := config@mp03.3
|
||||
endef
|
||||
TARGET_DEVICES += emplus_wap385c
|
||||
|
||||
define Device/hfcl_ion4x_w
|
||||
DEVICE_TITLE := HFCL ION4x_w
|
||||
DEVICE_DTS := qcom-ipq5018-hfcl-ion4x_w
|
||||
|
||||
@@ -26,6 +26,12 @@ edgecore,eap101)
|
||||
ucidef_set_led_netdev "poe" "poe" "green:wan" "eth0"
|
||||
ucidef_set_led_default "power" "POWER" "green:led_pwr" "on"
|
||||
;;
|
||||
emplus,wap386v2)
|
||||
ucidef_set_led_default "power" "POWER" "red:power" "on"
|
||||
ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth0" "tx rx link"
|
||||
ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wifi2" "phy1tpt"
|
||||
ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
|
||||
;;
|
||||
hfcl,ion4xi|\
|
||||
hfcl,ion4x|\
|
||||
hfcl,ion4x_2|\
|
||||
|
||||
@@ -34,10 +34,10 @@ qcom_setup_interfaces()
|
||||
ucidef_set_interface_lan "eth1"
|
||||
ucidef_set_interface_wan "eth0"
|
||||
;;
|
||||
cig,wf660a)
|
||||
cig,wf660a|\
|
||||
emplus,wap386v2)
|
||||
ucidef_set_interface_wan "eth0"
|
||||
;;
|
||||
|
||||
yuncore,fap650)
|
||||
ucidef_set_interface_lan "eth3 eth2 eth1 eth0"
|
||||
ucidef_set_interface_wan "eth4"
|
||||
@@ -76,6 +76,9 @@ qcom_setup_macs()
|
||||
ucidef_set_network_device_mac eth0 $wan_mac
|
||||
ip link set eth0 address $wan_mac
|
||||
;;
|
||||
emplus,wap386v2)
|
||||
wan_mac=$(cat /sys/class/net/eth0/address)
|
||||
;;
|
||||
yuncore,ax840)
|
||||
wan_mac=$(cat /sys/class/net/eth1/address)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
|
||||
@@ -76,6 +76,7 @@ case "$FIRMWARE" in
|
||||
cig,wf188n|\
|
||||
cig,wf660a|\
|
||||
edgecore,eap101|\
|
||||
emplus,wap386v2|\
|
||||
hfcl,ion4xi|\
|
||||
hfcl,ion4x|\
|
||||
hfcl,ion4x_2|\
|
||||
@@ -109,7 +110,8 @@ ath11k-macs)
|
||||
edgecore,eap101)
|
||||
ath11k_generate_macs_eap101
|
||||
;;
|
||||
cig,wf188n)
|
||||
cig,wf188n|\
|
||||
emplus,wap386v2)
|
||||
ath11k_generate_macs
|
||||
;;
|
||||
cig,wf660a)
|
||||
|
||||
@@ -122,6 +122,7 @@ platform_check_image() {
|
||||
wallys,dr6018|\
|
||||
wallys,dr6018-v4|\
|
||||
edgecore,eap101|\
|
||||
emplus,wap386v2|\
|
||||
hfcl,ion4xi|\
|
||||
hfcl,ion4x|\
|
||||
hfcl,ion4x_2|\
|
||||
@@ -145,7 +146,8 @@ platform_do_upgrade() {
|
||||
cig,wf660a)
|
||||
spi_nor_emmc_do_upgrade_bootconfig $1
|
||||
;;
|
||||
cig,wf188n)
|
||||
cig,wf188n|\
|
||||
emplus,wap386v2)
|
||||
[ -f /proc/boot_info/rootfs/upgradepartition ] && {
|
||||
CI_UBIPART="$(cat /proc/boot_info/rootfs/upgradepartition)"
|
||||
CI_BOOTCFG=1
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "ipq6018.dtsi"
|
||||
#include "ipq6018-cpr-regulator.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "Emplus WAP386 v2";
|
||||
compatible = "emplus,wap386v2", "qcom,ipq6018-cp03", "qcom,ipq6018";
|
||||
|
||||
aliases {
|
||||
/*
|
||||
* Aliases as required by u-boot
|
||||
* to patch MAC addresses
|
||||
*/
|
||||
ethernet0 = "/soc/dp1";
|
||||
|
||||
led-boot = &led_power;
|
||||
led-failsafe = &led_power;
|
||||
led-running = &led_power;
|
||||
led-upgrade = &led_power;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
bootargs-append = " swiotlb=1 coherent_pool=2M";
|
||||
};
|
||||
|
||||
/*
|
||||
* +=========+==============+========================+
|
||||
* | | | |
|
||||
* | Region | Start Offset | Size |
|
||||
* | | | |
|
||||
* +--------+--------------+-------------------------+
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | Linux | 0x41000000 | 139MB |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* +--------+--------------+-------------------------+
|
||||
* | TZ App | 0x49B00000 | 6MB |
|
||||
* +--------+--------------+-------------------------+
|
||||
*
|
||||
* From the available 145 MB for Linux in the first 256 MB,
|
||||
* we are reserving 6 MB for TZAPP.
|
||||
*
|
||||
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
|
||||
* for memory layout.
|
||||
*/
|
||||
|
||||
/* TZAPP is enabled only in default memory profile */
|
||||
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
|
||||
reserved-memory {
|
||||
tzapp:tzapp@49B00000 { /* TZAPPS */
|
||||
no-map;
|
||||
reg = <0x0 0x49B00000 0x0 0x00600000>;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <20 1>;
|
||||
|
||||
uart_pins: uart_pins {
|
||||
mux {
|
||||
pins = "gpio44", "gpio45";
|
||||
function = "blsp2_uart";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
spi_0_pins: spi_0_pins {
|
||||
mux {
|
||||
pins = "gpio38", "gpio39", "gpio40", "gpio41";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
button_pins: button_pins {
|
||||
reset_button {
|
||||
pins = "gpio9";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
mdio_pins: mdio_pinmux {
|
||||
mux_0 {
|
||||
pins = "gpio64";
|
||||
function = "mdc";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux_1 {
|
||||
pins = "gpio65";
|
||||
function = "mdio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux_2 {
|
||||
pins = "gpio75";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
leds_pins: leds_pins {
|
||||
led_5g {
|
||||
pins = "gpio31";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
led_2g {
|
||||
pins = "gpio30";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&soc {
|
||||
mdio@90000 {
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
pinctrl-names = "default";
|
||||
phy-reset-gpio = <&tlmm 75 0>;
|
||||
status = "ok";
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <3>;
|
||||
};
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
|
||||
ess-switch@3a000000 {
|
||||
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
|
||||
switch_lan_bmp = <0x08>; /* lan port bitmap */
|
||||
switch_wan_bmp = <0x10>; /* wan port bitmap */
|
||||
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
|
||||
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
|
||||
switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
|
||||
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
|
||||
qcom,port_phyinfo {
|
||||
port@0 {
|
||||
port_id = <2>;
|
||||
phy_address = <3>;
|
||||
};
|
||||
port@1 {
|
||||
port_id = <3>;
|
||||
phy_address = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <3>;
|
||||
reg = <0x3a001400 0x200>;
|
||||
qcom,mactype = <0>;
|
||||
local-mac-address = [000000000000];
|
||||
qcom,link-poll = <1>;
|
||||
qcom,phy-mdio-addr = <4>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
button@9 {
|
||||
label = "reset";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
pinctrl-0 = <&leds_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
led_power: led@28 {
|
||||
label = "red:power";
|
||||
gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "wap386v2:red:power";
|
||||
default-state = "on";
|
||||
};
|
||||
led@29 {
|
||||
label = "blue:wan";
|
||||
gpios = <&tlmm 29 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "wap386v2:blue:eth";
|
||||
default-state = "on";
|
||||
};
|
||||
led@30 {
|
||||
label = "blue:wifi2";
|
||||
gpios = <&tlmm 30 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "wap386v2:blue:2g";
|
||||
default-state = "on";
|
||||
};
|
||||
led@31 {
|
||||
label = "blue:wifi5";
|
||||
gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "wap386v2:blue:5g";
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart3 {
|
||||
pinctrl-0 = <&uart_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&spi_0 {
|
||||
pinctrl-0 = <&spi_0_pins>;
|
||||
pinctrl-names = "default";
|
||||
cs-select = <0>;
|
||||
status = "ok";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0>;
|
||||
compatible = "n25q128a11";
|
||||
linux,modalias = "m25p80", "n25q128a11";
|
||||
spi-max-frequency = <50000000>;
|
||||
use-default-sizes;
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
qcom,board_id = <0x30>;
|
||||
};
|
||||
|
||||
&pcie_phy {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
#if defined(__CNSS2__)
|
||||
status = "ok";
|
||||
#endif
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&qpic_nand {
|
||||
status = "ok";
|
||||
|
||||
nand@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
nand-ecc-strength = <4>;
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-bus-width = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
&ssphy_0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&nss_crypto {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&CPU0 {
|
||||
operating-points = <
|
||||
/* kHz uV (fixed) */
|
||||
864000 1100000
|
||||
1056000 1100000
|
||||
1320000 1100000
|
||||
1440000 1100000
|
||||
1608000 1100000
|
||||
1800000 1100000
|
||||
>;
|
||||
clock-latency = <200000>;
|
||||
};
|
||||
|
||||
&CPU1 {
|
||||
operating-points = <
|
||||
/* kHz uV (fixed) */
|
||||
864000 1100000
|
||||
1056000 1100000
|
||||
1320000 1100000
|
||||
1440000 1100000
|
||||
1608000 1100000
|
||||
1800000 1100000
|
||||
>;
|
||||
clock-latency = <200000>;
|
||||
};
|
||||
|
||||
&CPU2 {
|
||||
operating-points = <
|
||||
/* kHz uV (fixed) */
|
||||
864000 1100000
|
||||
1056000 1100000
|
||||
1320000 1100000
|
||||
1440000 1100000
|
||||
1608000 1100000
|
||||
1800000 1100000
|
||||
>;
|
||||
clock-latency = <200000>;
|
||||
};
|
||||
|
||||
&CPU3 {
|
||||
operating-points = <
|
||||
/* kHz uV (fixed) */
|
||||
864000 1100000
|
||||
1056000 1100000
|
||||
1320000 1100000
|
||||
1440000 1100000
|
||||
1608000 1100000
|
||||
1800000 1100000
|
||||
>;
|
||||
clock-latency = <200000>;
|
||||
};
|
||||
|
||||
&rpm_glink {
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -76,6 +76,15 @@ define Device/edgecore_eap101
|
||||
endef
|
||||
TARGET_DEVICES += edgecore_eap101
|
||||
|
||||
define Device/emplus_wap386v2
|
||||
DEVICE_TITLE := Emplus WAP386v2
|
||||
DEVICE_DTS := qcom-ipq6018-emplus-wap386v2
|
||||
DEVICE_DTS_CONFIG := config@cp03-c1
|
||||
SUPPORTED_DEVICES := emplus,wap386v2
|
||||
DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-env
|
||||
endef
|
||||
TARGET_DEVICES += emplus_wap386v2
|
||||
|
||||
define Device/indio_um-310ax-v1
|
||||
DEVICE_TITLE := Indio UM-310AX V1
|
||||
DEVICE_DTS := qcom-ipq6018-indio-um-310ax-v1
|
||||
|
||||
@@ -16,14 +16,14 @@ ath11k_generate_macs() {
|
||||
echo -ne \\x${mac3//:/\\x} >> /lib/firmware/ath11k-macs
|
||||
}
|
||||
|
||||
ath11k_generate_macs_sonicfi() {
|
||||
ath11k_generate_macs_rap650c() {
|
||||
mac=$(fw_printenv -n BaseMacAddress)
|
||||
[ -z "$mac" ] && return;
|
||||
|
||||
touch /lib/firmware/ath11k-macs
|
||||
eth=$(macaddr_canonicalize $mac)
|
||||
mac1=$(macaddr_add $eth 2)
|
||||
mac2=$(macaddr_add $eth 3)
|
||||
mac1=$(macaddr_add $eth 3)
|
||||
mac2=$(macaddr_add $eth 2)
|
||||
mac3=$(macaddr_add $eth 4)
|
||||
echo -ne \\x${mac1//:/\\x} >> /lib/firmware/ath11k-macs
|
||||
echo -ne \\x${mac2//:/\\x} >> /lib/firmware/ath11k-macs
|
||||
@@ -112,8 +112,8 @@ ath11k-macs)
|
||||
cig,wf196)
|
||||
ath11k_generate_macs_wf196
|
||||
;;
|
||||
sonicfi*)
|
||||
ath11k_generate_macs_sonicfi
|
||||
sonicfi,rap650c)
|
||||
ath11k_generate_macs_rap650c
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
return 0;
|
||||
- if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8))
|
||||
+ if (rate->nss < 1 || rate->nss > 8) {
|
||||
+ printk_once(1, "invalid rate->nss: %d\n", rate->nss);
|
||||
+ printk_once(KERN_WARNING "cfg80211_calculate_bitrate_he: invalid rate->nss: %d\n", rate->nss);
|
||||
return 0;
|
||||
-
|
||||
+ }
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -819,10 +819,7 @@ int ath11k_peer_delete(struct ath11k *ar
|
||||
#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
mutex_unlock(&ar->ab->base_ast_lock);
|
||||
#endif
|
||||
- ath11k_warn(ar->ab,
|
||||
- "failed to find peer vdev_id %d addr %pM in delete\n",
|
||||
- vdev_id, addr);
|
||||
- return -EINVAL;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
@@ -883,6 +880,7 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
struct ieee80211_vif *vif = arvif->vif;
|
||||
struct ath11k_sta *arsta;
|
||||
int ret, fbret;
|
||||
+ u8 vdev_id = 0;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
@@ -891,20 +889,21 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
"failed to create peer due to insufficient peer entry resource in firmware\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
+
|
||||
mutex_lock(&ar->ab->tbl_mtx_lock);
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
|
||||
+ if (peer)
|
||||
+ vdev_id = peer->vdev_id;
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+ mutex_unlock(&ar->ab->tbl_mtx_lock);
|
||||
+
|
||||
if (peer) {
|
||||
- if (peer->vdev_id == param->vdev_id) {
|
||||
- spin_unlock_bh(&ar->ab->base_lock);
|
||||
- mutex_unlock(&ar->ab->tbl_mtx_lock);
|
||||
+ if (vdev_id == param->vdev_id)
|
||||
return -EINVAL;
|
||||
- }
|
||||
- ath11k_peer_rhash_delete(ar->ab, peer);
|
||||
- }
|
||||
|
||||
- spin_unlock_bh(&ar->ab->base_lock);
|
||||
- mutex_unlock(&ar->ab->tbl_mtx_lock);
|
||||
+ ath11k_peer_delete(ar, vdev_id, param->peer_addr);
|
||||
+ }
|
||||
|
||||
ret = ath11k_wmi_send_peer_create_cmd(ar, param);
|
||||
if (ret) {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -28,7 +28,7 @@ void ath11k_dp_peer_cleanup(struct ath11
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, vdev_id, addr);
|
||||
if (!peer) {
|
||||
- ath11k_warn(ab, "failed to lookup peer %pM on vdev %d\n",
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to lookup peer %pM on vdev %d\n",
|
||||
addr, vdev_id);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
return;
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -1204,9 +1204,9 @@ int ath11k_dp_rx_ampdu_stop(struct ath11
|
||||
|
||||
peer = ath11k_peer_find(ab, vdev_id, params->sta->addr);
|
||||
if (!peer) {
|
||||
- ath11k_warn(ab, "failed to find the peer to stop rx aggregation\n");
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to find the peer to stop rx aggregation\n");
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
- return -ENOENT;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
paddr = peer->rx_tid[params->tid].paddr;
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4075,7 +4075,7 @@ static int ath11k_clear_peer_keys(struct
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, addr);
|
||||
if (!peer) {
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
- return -ENOENT;
|
||||
+ return 0;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(keys); i++) {
|
||||
keys[i]= peer->keys[i];
|
||||
@@ -4325,6 +4325,10 @@ static int ath11k_mac_op_set_key(struct
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
|
||||
+ if (!peer && cmd == DISABLE_KEY) {
|
||||
+ ret = 0;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
|
||||
/* TODO: Check if vdev specific security cfg is mandatory */
|
||||
ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher);
|
||||
@@ -5961,7 +5965,7 @@ static void ath11k_mac_op_sta_rc_update(
|
||||
peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
|
||||
if (!peer) {
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
- ath11k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n",
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac sta rc update failed to find peer %pM on vdev %i\n",
|
||||
sta->addr, arvif->vdev_id);
|
||||
return;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -8425,7 +8425,7 @@ static void ath11k_peer_sta_kickout_even
|
||||
peer = ath11k_peer_find_by_addr(ab, arg.mac_addr);
|
||||
if (!peer) {
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
- ath11k_warn(ab, "peer not found %pM\n",
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_WMI, "peer not found %pM\n",
|
||||
arg.mac_addr);
|
||||
goto exit;
|
||||
}
|
||||
@@ -169,7 +169,8 @@
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-mode = "sgmii";
|
||||
phy-handle = <&phy1>; // add phy handler
|
||||
phy-handle = <&phy30>;
|
||||
phy-handle2 = <&phy1>;
|
||||
mtd-mac-address = <&factory 0x24>;
|
||||
};
|
||||
|
||||
@@ -181,9 +182,9 @@
|
||||
mtd-mac-address = <&factory 0x2a>;
|
||||
};
|
||||
|
||||
mdio: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mdio: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-id03a2.9461";
|
||||
@@ -193,6 +194,16 @@
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
|
||||
phy30: ethernet-phy@30 { // AN8801SB
|
||||
compatible = "ethernet-phy-idc0ff.0421";
|
||||
reg = <30>; //0x1e
|
||||
phy-mode = "sgmii";
|
||||
full-duplex;
|
||||
pause;
|
||||
airoha,surge = <1>;
|
||||
airoha,polarity = <2>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-id03a2.9471";
|
||||
reg = <24>; // set phy address to 0x18
|
||||
@@ -200,9 +211,8 @@
|
||||
reset-assert-us = <600>;
|
||||
reset-deassert-us = <20000>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&hnat {
|
||||
|
||||
@@ -113,7 +113,6 @@ static const struct AIR_LED_CFG_T led_cfg_dlt[MAX_LED_SIZE] = {
|
||||
/* LED2 */
|
||||
{LED_ENABLE, AIR_LED_GPIO9, AIR_ACTIVE_LOW, AIR_LED2_ON, AIR_LED2_BLK},
|
||||
};
|
||||
|
||||
static const u16 led_blink_cfg_dlt = AIR_LED_BLK_DUR_64M;
|
||||
/* RGMII delay */
|
||||
static const u8 rxdelay_force = FALSE;
|
||||
@@ -140,7 +139,6 @@ static int __air_buckpbus_reg_write(struct phy_device *phydev, u32 addr,
|
||||
err |= mbus->write(mbus, phy_addr, 0x13, (u16)(data >> 16));
|
||||
err |= mbus->write(mbus, phy_addr, 0x14, (u16)(data & 0xffff));
|
||||
err |= mbus->write(mbus, phy_addr, 0x1F, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -167,6 +165,41 @@ static u32 __air_buckpbus_reg_read(struct phy_device *phydev, u32 addr)
|
||||
return data;
|
||||
}
|
||||
|
||||
static u32 __air_buckpbus_reg_modify(struct phy_device *phydev, u32 addr,
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
int err = 0;
|
||||
u32 data_h, data_l, data_old, data_new;
|
||||
int phy_addr = phydev_phy_addr(phydev);
|
||||
struct mii_bus *mbus = phydev_mdiobus(phydev);
|
||||
|
||||
err = mbus->write(mbus, phy_addr, 0x1F, 4);
|
||||
err |= mbus->write(mbus, phy_addr, 0x10, 0);
|
||||
err |= mbus->write(mbus, phy_addr, 0x15, (u16)(addr >> 16));
|
||||
err |= mbus->write(mbus, phy_addr, 0x16, (u16)(addr & 0xffff));
|
||||
data_h = mbus->read(mbus, phy_addr, 0x17);
|
||||
data_l = mbus->read(mbus, phy_addr, 0x18);
|
||||
if (err < 0) {
|
||||
mbus->write(mbus, phy_addr, 0x1F, 0);
|
||||
return INVALID_DATA;
|
||||
}
|
||||
|
||||
data_old = ((data_h & 0xffff) << 16) | (data_l & 0xffff);
|
||||
data_new = (data_old & ~mask) | set;
|
||||
if (data_new == data_old) {
|
||||
mbus->write(mbus, phy_addr, 0x1F, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err |= mbus->write(mbus, phy_addr, 0x11, (u16)(addr >> 16));
|
||||
err |= mbus->write(mbus, phy_addr, 0x12, (u16)(addr & 0xffff));
|
||||
err |= mbus->write(mbus, phy_addr, 0x13, (u16)(data_new >> 16));
|
||||
err |= mbus->write(mbus, phy_addr, 0x14, (u16)(data_new & 0xffff));
|
||||
err |= mbus->write(mbus, phy_addr, 0x1F, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int air_buckpbus_reg_write(struct phy_device *phydev, u32 addr, u32 data)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -189,82 +222,18 @@ static u32 air_buckpbus_reg_read(struct phy_device *phydev, u32 addr)
|
||||
return data;
|
||||
}
|
||||
|
||||
static int __an8801_cl45_write(struct phy_device *phydev, int devad, u16 reg,
|
||||
u16 val)
|
||||
{
|
||||
u32 addr = (AN8801_EPHY_ADDR | AN8801_CL22 | (devad << 18) |
|
||||
(reg << 2));
|
||||
|
||||
return __air_buckpbus_reg_write(phydev, addr, val);
|
||||
}
|
||||
|
||||
static int __an8801_cl45_read(struct phy_device *phydev, int devad, u16 reg)
|
||||
{
|
||||
u32 addr = (AN8801_EPHY_ADDR | AN8801_CL22 | (devad << 18) |
|
||||
(reg << 2));
|
||||
|
||||
return __air_buckpbus_reg_read(phydev, addr);
|
||||
}
|
||||
|
||||
int __an8801_modify_cl45_changed(struct phy_device *phydev, int devad, u32 regnum,
|
||||
u16 mask, u16 set)
|
||||
{
|
||||
int new, ret;
|
||||
|
||||
ret = __an8801_cl45_read(phydev, devad, regnum);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = (ret & ~mask) | set;
|
||||
if (new == ret)
|
||||
return 0;
|
||||
|
||||
ret = __an8801_cl45_write(phydev, devad, regnum, new);
|
||||
|
||||
return ret < 0 ? ret : 1;
|
||||
}
|
||||
|
||||
static int an8801_modify_cl45_changed(struct phy_device *phydev, int devad,
|
||||
u32 regnum, u16 mask, u16 set)
|
||||
static int air_buckpbus_reg_modify(struct phy_device *phydev, u32 addr,
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mdiobus_lock(phydev);
|
||||
err = __an8801_modify_cl45_changed(phydev, devad, regnum, mask, set);
|
||||
err = __air_buckpbus_reg_modify(phydev, addr, mask, set);
|
||||
mdiobus_unlock(phydev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int an8801_cl45_write(struct phy_device *phydev, int devad, u16 reg,
|
||||
u16 val)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mdiobus_lock(phydev);
|
||||
err = __an8801_cl45_write(phydev, devad, reg, val);
|
||||
mdiobus_unlock(phydev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int an8801_cl45_read(struct phy_device *phydev, int devad, u16 reg,
|
||||
u16 *read_data)
|
||||
{
|
||||
int data = 0;
|
||||
|
||||
mdiobus_lock(phydev);
|
||||
data = __an8801_cl45_read(phydev, devad, reg);
|
||||
mdiobus_unlock(phydev);
|
||||
|
||||
if (data == INVALID_DATA)
|
||||
return -EINVAL;
|
||||
|
||||
*read_data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int air_sw_reset(struct phy_device *phydev)
|
||||
{
|
||||
u32 reg_value;
|
||||
@@ -298,50 +267,36 @@ static int an8801_led_set_usr_def(struct phy_device *phydev, u8 entity,
|
||||
|
||||
on_evt |= LED_ON_EN;
|
||||
|
||||
err = an8801_cl45_write(phydev, 0x1f, LED_ON_CTRL(entity), on_evt);
|
||||
err = phy_write_mmd(phydev, 0x1f, LED_ON_CTRL(entity), on_evt);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
return an8801_cl45_write(phydev, 0x1f, LED_BLK_CTRL(entity), blk_evt);
|
||||
return phy_write_mmd(phydev, 0x1f, LED_BLK_CTRL(entity), blk_evt);
|
||||
}
|
||||
|
||||
static int an8801_led_set_mode(struct phy_device *phydev, u8 mode)
|
||||
{
|
||||
int err;
|
||||
u16 data;
|
||||
|
||||
err = an8801_cl45_read(phydev, 0x1f, LED_BCR, &data);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
switch (mode) {
|
||||
case AIR_LED_MODE_DISABLE:
|
||||
data &= ~LED_BCR_EXT_CTRL;
|
||||
data &= ~LED_BCR_MODE_MASK;
|
||||
data |= LED_BCR_MODE_DISABLE;
|
||||
break;
|
||||
return phy_modify_mmd(phydev, 0x1f, LED_BCR,
|
||||
(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN),
|
||||
0x0);
|
||||
case AIR_LED_MODE_USER_DEFINE:
|
||||
data |= (LED_BCR_EXT_CTRL | LED_BCR_CLK_EN);
|
||||
return phy_modify_mmd(phydev, 0x1f, LED_BCR,
|
||||
(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN),
|
||||
(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return an8801_cl45_write(phydev, 0x1f, LED_BCR, data);
|
||||
dev_err(phydev_dev(phydev),
|
||||
"LED mode %d is not supported\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int an8801_led_set_state(struct phy_device *phydev, u8 entity, u8 state)
|
||||
{
|
||||
u16 data;
|
||||
int err;
|
||||
|
||||
err = an8801_cl45_read(phydev, 0x1f, LED_ON_CTRL(entity), &data);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (state)
|
||||
data |= LED_ON_EN;
|
||||
else
|
||||
data &= ~LED_ON_EN;
|
||||
|
||||
return an8801_cl45_write(phydev, 0x1f, LED_ON_CTRL(entity), data);
|
||||
return phy_modify_mmd(phydev, 0x1f, LED_ON_CTRL(entity), LED_ON_EN,
|
||||
(state) ? LED_ON_EN : 0x0);
|
||||
}
|
||||
|
||||
static int an8801_led_init(struct phy_device *phydev)
|
||||
@@ -352,12 +307,12 @@ static int an8801_led_init(struct phy_device *phydev)
|
||||
u32 data;
|
||||
u16 led_blink_cfg = priv->led_blink_cfg;
|
||||
|
||||
ret = an8801_cl45_write(phydev, 0x1f, LED_BLK_DUR,
|
||||
ret = phy_write_mmd(phydev, 0x1f, LED_BLK_DUR,
|
||||
LED_BLINK_DURATION(led_blink_cfg));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = an8801_cl45_write(phydev, 0x1f, LED_ON_DUR,
|
||||
ret = phy_write_mmd(phydev, 0x1f, LED_ON_DUR,
|
||||
(LED_BLINK_DURATION(led_blink_cfg) >> 1));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -406,6 +361,56 @@ static int an8801_led_init(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8801_ack_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
|
||||
air_buckpbus_reg_write(phydev, 0x10285404, 0x102);
|
||||
reg_val = air_buckpbus_reg_read(phydev, 0x10285400);
|
||||
air_buckpbus_reg_write(phydev, 0x10285400, 0x0);
|
||||
air_buckpbus_reg_write(phydev, 0x10285400, reg_val | 0x10);
|
||||
air_buckpbus_reg_write(phydev, 0x10285404, 0x12);
|
||||
air_buckpbus_reg_write(phydev, 0x10285704, 0x1f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8801_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
|
||||
air_buckpbus_reg_write(phydev, 0x1000007c, BIT(AIR_INTERRUPT_GPIO) << 16);
|
||||
air_buckpbus_reg_modify(phydev, 0x10285700, 0x1, 0x1);
|
||||
} else {
|
||||
air_buckpbus_reg_write(phydev, 0x1000007c, 0x0);
|
||||
air_buckpbus_reg_modify(phydev, 0x10285700, 0x1, 0x0);
|
||||
}
|
||||
an8801_ack_interrupt(phydev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8801_did_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
|
||||
reg_val = air_buckpbus_reg_read(phydev, 0x10285704);
|
||||
|
||||
if (reg_val & 0x11)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(5, 11, 0) < LINUX_VERSION_CODE)
|
||||
static irqreturn_t an8801_handle_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
if (!an8801_did_interrupt(phydev))
|
||||
return IRQ_NONE;
|
||||
|
||||
an8801_ack_interrupt(phydev);
|
||||
phy_trigger_machine(phydev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int findClosestNumber(const u16 *arr, u16 size, u16 target)
|
||||
{
|
||||
int left = 0, right = size - 1;
|
||||
@@ -431,77 +436,77 @@ static int findClosestNumber(const u16 *arr, u16 size, u16 target)
|
||||
static int an8801sb_i2mpb_config(struct phy_device *phydev)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 cl45_value = 0, temp_cl45 = 0, set = 0;
|
||||
u16 cl45_value = 0, temp_cl45 = 0;
|
||||
u16 mask = 0;
|
||||
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x12, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x12);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(15, 10)) + (6 << 10);
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x12, GENMASK(15, 10), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x12, GENMASK(15, 10), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x16, &temp_cl45);
|
||||
temp_cl45 = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x16);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, temp_cl45);
|
||||
mask = GENMASK(15, 10) | GENMASK(5, 0);
|
||||
cl45_value = (temp_cl45 & GENMASK(15, 10)) + (9 << 10);
|
||||
cl45_value = ((temp_cl45 & GENMASK(5, 0)) + 6) | cl45_value;
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x16, mask, cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x16, mask, cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x17, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x17);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x17, GENMASK(13, 8), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x17, GENMASK(13, 8), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x18, &temp_cl45);
|
||||
temp_cl45 = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x18);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, temp_cl45);
|
||||
mask = GENMASK(13, 8) | GENMASK(5, 0);
|
||||
cl45_value = (temp_cl45 & GENMASK(13, 8)) + (9 << 8);
|
||||
cl45_value = ((temp_cl45 & GENMASK(5, 0)) + 6) | cl45_value;
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x18, mask, cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x18, mask, cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x19, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x19);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x19, GENMASK(13, 8), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x19, GENMASK(13, 8), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x20, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x20);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(5, 0)) + 6;
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x20, GENMASK(5, 0), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x20, GENMASK(5, 0), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x21, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x21);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x21, GENMASK(13, 8), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x21, GENMASK(13, 8), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x22, &cl45_value);
|
||||
cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x22);
|
||||
dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
|
||||
cl45_value = (cl45_value & GENMASK(5, 0)) + 6;
|
||||
ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x22, GENMASK(5, 0), cl45_value);
|
||||
ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x22, GENMASK(5, 0), cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x23, 0x883);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x24, 0x883);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x25, 0x883);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x26, 0x883);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x0, 0x100);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x1, 0x1bc);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x2, 0x1d0);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x3, 0x186);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x4, 0x202);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x5, 0x20e);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x6, 0x300);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x7, 0x3c0);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x8, 0x3d0);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x9, 0x317);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0xa, 0x206);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0xb, 0xe);
|
||||
ret = phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x23, 0x883);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x24, 0x883);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x25, 0x883);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x26, 0x883);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x0, 0x100);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x1, 0x1bc);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x2, 0x1d0);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x3, 0x186);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x4, 0x202);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x5, 0x20e);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x6, 0x300);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x7, 0x3c0);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x8, 0x3d0);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x9, 0x317);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0xa, 0x206);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0xb, 0xe);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -510,14 +515,14 @@ static int an8801sb_i2mpb_config(struct phy_device *phydev)
|
||||
}
|
||||
|
||||
void update_r50_value(struct phy_device *phydev,
|
||||
u16 *cl45_value, int pos1, int pos2)
|
||||
u16 *cl45_value, int pos1, int pos2)
|
||||
{
|
||||
*cl45_value &= ~(0x007f << 8);
|
||||
*cl45_value |= ((r50ohm_table[pos1]) & 0x007f) << 8;
|
||||
*cl45_value &= ~(0x007f);
|
||||
*cl45_value |= (r50ohm_table[pos2]) & 0x007f;
|
||||
dev_dbg(phydev_dev(phydev), "Read: r50ohm_tx_1=%d r50ohm_tx_2=%d\n",
|
||||
r50ohm_table[pos1], r50ohm_table[pos2]);
|
||||
r50ohm_table[pos1], r50ohm_table[pos2]);
|
||||
}
|
||||
|
||||
int calculate_position(int pos, int shift, int table_size)
|
||||
@@ -529,7 +534,7 @@ int calculate_position(int pos, int shift, int table_size)
|
||||
}
|
||||
|
||||
int process_r50(struct phy_device *phydev, int reg,
|
||||
u16 *cl45_value, u16 *r50ohm_tx_a, u16 *r50ohm_tx_b)
|
||||
u16 *cl45_value, u16 *r50ohm_tx_a, u16 *r50ohm_tx_b)
|
||||
{
|
||||
int pos1 = findClosestNumber(r50ohm_table, r50ohm_table_size, *r50ohm_tx_a);
|
||||
int pos2 = findClosestNumber(r50ohm_table, r50ohm_table_size, *r50ohm_tx_b);
|
||||
@@ -539,7 +544,7 @@ int process_r50(struct phy_device *phydev, int reg,
|
||||
pos2 = calculate_position(pos2, R50_SHIFT, r50ohm_table_size);
|
||||
|
||||
update_r50_value(phydev, cl45_value, pos1, pos2);
|
||||
return an8801_cl45_write(phydev, 0x1e, reg, *cl45_value);
|
||||
return phy_write_mmd(phydev, 0x1e, reg, *cl45_value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -558,10 +563,10 @@ static int an8801r_of_init(struct phy_device *phydev)
|
||||
return -1;
|
||||
}
|
||||
if (val < AIR_RGMII_DELAY_NOSTEP ||
|
||||
val > AIR_RGMII_DELAY_STEP_7) {
|
||||
val > AIR_RGMII_DELAY_STEP_7) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"airoha,rxclk-delay value %u out of range.",
|
||||
val);
|
||||
"airoha,rxclk-delay value %u out of range.",
|
||||
val);
|
||||
return -1;
|
||||
}
|
||||
priv->rxdelay_force = TRUE;
|
||||
@@ -574,14 +579,14 @@ static int an8801r_of_init(struct phy_device *phydev)
|
||||
if (of_property_read_u32(of_node, "airoha,txclk-delay",
|
||||
&val) != 0) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"airoha,txclk-delay value is invalid.");
|
||||
"airoha,txclk-delay value is invalid.");
|
||||
return -1;
|
||||
}
|
||||
if (val < AIR_RGMII_DELAY_NOSTEP ||
|
||||
val > AIR_RGMII_DELAY_STEP_7) {
|
||||
val > AIR_RGMII_DELAY_STEP_7) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"airoha,txclk-delay value %u out of range.",
|
||||
val);
|
||||
"airoha,txclk-delay value %u out of range.",
|
||||
val);
|
||||
return -1;
|
||||
}
|
||||
priv->txdelay_force = TRUE;
|
||||
@@ -603,10 +608,10 @@ static int an8801sb_of_init(struct phy_device *phydev)
|
||||
return -1;
|
||||
}
|
||||
if (val < AIR_POL_TX_NOR_RX_REV ||
|
||||
val > AIR_POL_TX_REV_RX_NOR) {
|
||||
val > AIR_POL_TX_REV_RX_NOR) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"airoha,polarity value %u out of range.",
|
||||
val);
|
||||
"airoha,polarity value %u out of range.",
|
||||
val);
|
||||
return -1;
|
||||
}
|
||||
priv->pol = val;
|
||||
@@ -615,15 +620,15 @@ static int an8801sb_of_init(struct phy_device *phydev)
|
||||
|
||||
if (of_find_property(of_node, "airoha,surge", NULL)) {
|
||||
if (of_property_read_u32(of_node, "airoha,surge",
|
||||
&val) != 0) {
|
||||
&val) != 0) {
|
||||
dev_err(phydev_dev(phydev), "airoha,surge value is invalid.");
|
||||
return -1;
|
||||
}
|
||||
if (val < AIR_SURGE_0R ||
|
||||
val > AIR_SURGE_5R) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"airoha,surge value %u out of range.",
|
||||
val);
|
||||
"airoha,surge value %u out of range.",
|
||||
val);
|
||||
return -1;
|
||||
}
|
||||
priv->surge = val;
|
||||
@@ -693,23 +698,19 @@ int an8801sb_surge_protect_cfg(struct phy_device *phydev)
|
||||
u16 cl45_value = 0;
|
||||
|
||||
if (priv->surge) {
|
||||
ret = an8801_cl45_read(phydev, 0x1e, 0x174, &cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
cl45_value = phy_read_mmd(phydev, 0x1e, 0x174);
|
||||
r50ohm_tx_a = (cl45_value >> 8) & 0x007f;
|
||||
r50ohm_tx_b = cl45_value & 0x007f;
|
||||
dev_dbg(phydev_dev(phydev), "Read: (0x174) value=0x%04x r50ohm_tx_a=%d r50ohm_tx_b=%d\n",
|
||||
cl45_value, r50ohm_tx_a, r50ohm_tx_b);
|
||||
cl45_value, r50ohm_tx_a, r50ohm_tx_b);
|
||||
ret = process_r50(phydev, 0x174, &cl45_value, &r50ohm_tx_a, &r50ohm_tx_b);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = an8801_cl45_read(phydev, 0x1e, 0x175, &cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
cl45_value = phy_read_mmd(phydev, 0x1e, 0x175);
|
||||
r50ohm_tx_c = (cl45_value >> 8) & 0x007f;
|
||||
r50ohm_tx_d = cl45_value & 0x007f;
|
||||
dev_dbg(phydev_dev(phydev), "Read: (0x175) value=0x%04x r50ohm_tx_c=%d r50ohm_tx_d=%d\n",
|
||||
cl45_value, r50ohm_tx_c, r50ohm_tx_d);
|
||||
cl45_value, r50ohm_tx_c, r50ohm_tx_d);
|
||||
ret = process_r50(phydev, 0x175, &cl45_value, &r50ohm_tx_c, &r50ohm_tx_d);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -764,10 +765,10 @@ static int an8801sb_config_init(struct phy_device *phydev)
|
||||
dev_info(phydev_dev(phydev),
|
||||
"Tx, Rx Polarity : %08x\n", pbus_value);
|
||||
|
||||
ret = an8801_cl45_write(phydev, MMD_DEV_VSPEC2, 0x600, 0x1e);
|
||||
ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC2, 0x601, 0x02);
|
||||
ret = phy_write_mmd(phydev, MMD_DEV_VSPEC2, 0x600, 0x1e);
|
||||
ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC2, 0x601, 0x02);
|
||||
|
||||
ret |= an8801_cl45_write(phydev, 7, 60, 0x0);
|
||||
ret |= phy_write_mmd(phydev, 7, 60, 0x0);
|
||||
if (ret != 0) {
|
||||
dev_err(phydev_dev(phydev),
|
||||
"AN8801SB initialize fail, ret %d !\n", ret);
|
||||
@@ -940,7 +941,7 @@ static ssize_t an8801_polarity_write(struct file *file, const char __user *ptr,
|
||||
}
|
||||
|
||||
static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
|
||||
size_t len, loff_t *off)
|
||||
size_t len, loff_t *off)
|
||||
{
|
||||
struct phy_device *phydev = file->private_data;
|
||||
char buf[64], param1[32], param2[32];
|
||||
@@ -955,7 +956,7 @@ static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
|
||||
if (count > sizeof(buf) - 1)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(buf, ptr, len))
|
||||
return -EFAULT;
|
||||
return -EFAULT;
|
||||
|
||||
ret = sscanf(buf, "%s %s", param1, param2);
|
||||
if (ret < 0)
|
||||
@@ -991,16 +992,16 @@ static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
|
||||
pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x\n",
|
||||
phydev_phy_addr(phydev), devad, reg, val);
|
||||
|
||||
ret = an8801_cl45_write(phydev, devad, reg, val);
|
||||
ret = phy_write_mmd(phydev, devad, reg, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
an8801_cl45_read(phydev, devad, reg, ®_val);
|
||||
reg_val = phy_read_mmd(phydev, devad, reg);
|
||||
pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x confirm..\n",
|
||||
phydev_phy_addr(phydev), devad, reg, reg_val);
|
||||
} else if (!strncmp("r", param2, strlen("r"))) {
|
||||
if (sscanf(buf, "cl45 r %x %x", &devad, ®) == -1)
|
||||
return -EFAULT;
|
||||
an8801_cl45_read(phydev, devad, reg, ®_val);
|
||||
reg_val = phy_read_mmd(phydev, devad, reg);
|
||||
pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x\n",
|
||||
phydev_phy_addr(phydev), devad, reg, reg_val);
|
||||
} else {
|
||||
@@ -1020,7 +1021,6 @@ static int an8801_counter_show(struct seq_file *seq, void *v)
|
||||
struct phy_device *phydev = seq->private;
|
||||
int ret = 0;
|
||||
u32 pkt_cnt = 0;
|
||||
struct mii_bus *mbus = phydev_mdiobus(phydev);
|
||||
|
||||
seq_puts(seq, "==========AIR PHY COUNTER==========\n");
|
||||
seq_puts(seq, "|\t<<SERDES COUNTER>>\n");
|
||||
@@ -1143,8 +1143,9 @@ static ssize_t an8801_debugfs_pbus(struct file *file,
|
||||
if (buf[0] == 'w') {
|
||||
if (sscanf(buf, "w %x %x", ®, &val) == -1)
|
||||
return -EFAULT;
|
||||
|
||||
pr_notice("\nphy=0x%x, reg=0x%x, val=0x%x\n",
|
||||
phydev_phy_addr(phydev), reg, val);
|
||||
phydev_phy_addr(phydev), reg, val);
|
||||
|
||||
ret = air_buckpbus_reg_write(phydev, reg, val);
|
||||
if (ret < 0)
|
||||
@@ -1188,10 +1189,9 @@ int an8801_info_show(struct seq_file *seq, void *v)
|
||||
for (reg = MII_BMCR; reg <= MII_STAT1000; reg++) {
|
||||
if ((reg <= MII_LPA) || (reg >= MII_CTRL1000))
|
||||
seq_printf(seq, "| RG_MII 0x%02x : 0x%08x\n",
|
||||
reg, phy_read(phydev, reg));
|
||||
reg, phy_read(phydev, reg));
|
||||
}
|
||||
seq_puts(seq, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1231,10 +1231,10 @@ static const struct file_operations an8801_polarity_fops = {
|
||||
};
|
||||
|
||||
static const struct file_operations an8801_mdio_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.write = an8801_mdio_write,
|
||||
.llseek = noop_llseek,
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.write = an8801_mdio_write,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
int an8801_debugfs_init(struct phy_device *phydev)
|
||||
@@ -1354,13 +1354,22 @@ static int an8801sb_read_status(struct phy_device *phydev)
|
||||
if (phydev->link == LINK_DOWN) {
|
||||
prespeed = 0;
|
||||
phydev->speed = 0;
|
||||
ret |= an8801_cl45_write(
|
||||
ret |= phy_write_mmd(
|
||||
phydev, MMD_DEV_VSPEC2, PHY_PRE_SPEED_REG, prespeed);
|
||||
|
||||
mdelay(10); /* delay 10 ms */
|
||||
reg_value = air_buckpbus_reg_read(phydev, 0x10220010);
|
||||
reg_value &= 0x7fff;
|
||||
air_buckpbus_reg_write(phydev, 0x10220010, reg_value);
|
||||
|
||||
reg_value = air_buckpbus_reg_read(phydev, 0x10220000);
|
||||
reg_value |= AN8801SB_SGMII_AN0_ANRESTART;
|
||||
air_buckpbus_reg_write(phydev, 0x10220000, reg_value);
|
||||
}
|
||||
|
||||
if (prespeed != phydev->speed && phydev->link == LINK_UP) {
|
||||
prespeed = phydev->speed;
|
||||
ret |= an8801_cl45_write(
|
||||
ret |= phy_write_mmd(
|
||||
phydev, MMD_DEV_VSPEC2, PHY_PRE_SPEED_REG, prespeed);
|
||||
dev_info(phydev_dev(phydev), "AN8801SB SPEED %d\n", prespeed);
|
||||
while (an_retry > 0) {
|
||||
@@ -1374,28 +1383,19 @@ static int an8801sb_read_status(struct phy_device *phydev)
|
||||
mdelay(10); /* delay 10 ms */
|
||||
|
||||
|
||||
if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
dev_info(phydev_dev(phydev),
|
||||
"AN8801SB force speed = %d\n", prespeed);
|
||||
if (prespeed == SPEED_1000) {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220010, 0xd801);
|
||||
} else if (prespeed == SPEED_100) {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220010, 0xd401);
|
||||
} else {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220010, 0xd001);
|
||||
}
|
||||
|
||||
reg_value = air_buckpbus_reg_read(
|
||||
phydev, 0x10220000);
|
||||
reg_value |= AN8801SB_SGMII_AN0_ANRESTART;
|
||||
if (prespeed == SPEED_1000) {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220000, reg_value);
|
||||
phydev, 0x10220010, 0xd801);
|
||||
} else if (prespeed == SPEED_100) {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220010, 0xd401);
|
||||
} else {
|
||||
air_buckpbus_reg_write(
|
||||
phydev, 0x10220010, 0xd001);
|
||||
}
|
||||
|
||||
reg_value = air_buckpbus_reg_read(phydev, 0x10220000);
|
||||
reg_value |= AN8801SB_SGMII_AN0_RESET;
|
||||
reg_value |= (AN8801SB_SGMII_AN0_RESET | AN8801SB_SGMII_AN0_ANRESTART);
|
||||
air_buckpbus_reg_write(phydev, 0x10220000, reg_value);
|
||||
}
|
||||
return ret;
|
||||
@@ -1451,9 +1451,12 @@ static struct phy_driver airoha_driver[] = {
|
||||
.probe = an8801_phy_probe,
|
||||
.remove = an8801_phy_remove,
|
||||
.read_status = an8801_read_status,
|
||||
#if (KERNEL_VERSION(4, 5, 0) < LINUX_VERSION_CODE)
|
||||
.read_mmd = __an8801_cl45_read,
|
||||
.write_mmd = __an8801_cl45_write,
|
||||
.config_intr = an8801_config_intr,
|
||||
#if (KERNEL_VERSION(5, 11, 0) < LINUX_VERSION_CODE)
|
||||
.handle_interrupt = an8801_handle_interrupt,
|
||||
#else
|
||||
.did_interrupt = an8801_did_interrupt,
|
||||
.ack_interrupt = an8801_ack_interrupt,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
/* NAMING DECLARATIONS
|
||||
*/
|
||||
#define AN8801_DRIVER_VERSION "1.1.4"
|
||||
#define AN8801_DRIVER_VERSION "1.1.6"
|
||||
|
||||
#define DEBUGFS_COUNTER "counter"
|
||||
#define DEBUGFS_INFO "driver_info"
|
||||
#define DEBUGFS_INFO "driver_info"
|
||||
#define DEBUGFS_PBUS_OP "pbus_op"
|
||||
#define DEBUGFS_POLARITY "polarity"
|
||||
#define DEBUGFS_MDIO "mdio"
|
||||
@@ -88,7 +88,7 @@
|
||||
#define LED_BLK_EVT_1000M_RX BIT(1)
|
||||
#define LED_BLK_EVT_1000M_TX BIT(0)
|
||||
|
||||
#define UNIT_LED_BLINK_DURATION 1024
|
||||
#define UNIT_LED_BLINK_DURATION 780
|
||||
|
||||
/* Serdes auto negotation restart */
|
||||
#define AN8801SB_SGMII_AN0_ANRESTART (0x0200)
|
||||
@@ -135,6 +135,9 @@ For reference only
|
||||
#define LED_BLINK_DURATION(f) (UNIT_LED_BLINK_DURATION << (f))
|
||||
#define LED_GPIO_SEL(led, gpio) ((led) << ((gpio) * 3))
|
||||
|
||||
/* Interrupt GPIO number, should not conflict with LED */
|
||||
#define AIR_INTERRUPT_GPIO 3
|
||||
|
||||
/* DATA TYPE DECLARATIONS
|
||||
*/
|
||||
enum AIR_LED_GPIO_PIN_T {
|
||||
|
||||
@@ -587,7 +587,7 @@ static int en8801s_phase1_init(struct phy_device *phydev)
|
||||
|
||||
phydev->dev_flags = PHY_STATE_INIT;
|
||||
|
||||
dev_info(dev, "Phase1 initialize OK ! (%s)\n", EN8801S_DRIVER_VERSION);
|
||||
dev_info(dev, "Phase1 initialize OK ! (%s) 10Te TP_IDL fixed.\n", EN8801S_DRIVER_VERSION);
|
||||
if (priv->pro_version == 4) {
|
||||
ret = en8801s_phase2_init(phydev);
|
||||
if (ret != 0) {
|
||||
@@ -811,14 +811,7 @@ static int en8801s_phase2_init(struct phy_device *phydev)
|
||||
retry--;
|
||||
}
|
||||
pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C38); /* RAW#2 */
|
||||
ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x12, &cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
GPHY_RG_1E_012.DATA = cl45_value;
|
||||
GPHY_RG_1E_012.DataBitField.da_tx_i2mpb_a_tbt =
|
||||
(u16)(pbus_data & 0x03f);
|
||||
ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x12,
|
||||
GPHY_RG_1E_012.DATA);
|
||||
ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x12, 0xA018);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x17, &cl45_value);
|
||||
@@ -893,6 +886,17 @@ static int en8801s_phase2_init(struct phy_device *phydev)
|
||||
}
|
||||
}
|
||||
|
||||
//Fix 10Te TP_IDL
|
||||
ret = airoha_cl45_read(mbus, phy_addr, 0x1E,
|
||||
0x1A3, &cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
cl45_value &= ~0xf0;
|
||||
ret = airoha_cl45_write(mbus, phy_addr, 0x1E,
|
||||
0x1A3, cl45_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->first_init = false;
|
||||
dev_info(phydev_dev(phydev), "Phase2 initialize OK !\n");
|
||||
return 0;
|
||||
|
||||
@@ -31,7 +31,10 @@ mediatek_setup_interfaces()
|
||||
;;
|
||||
sonicfi,rap630w-211g)
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
|
||||
;;
|
||||
;;
|
||||
emplus,wap588m)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
;;
|
||||
*)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
|
||||
@@ -8,6 +8,9 @@ boot() {
|
||||
edgecore,eap112)
|
||||
bootcount=$(fw_printenv -n bootcount)
|
||||
[ "$bootcount" != 0 ] && fw_setenv bootcount 0
|
||||
# enable dualboot
|
||||
avail=$(fw_printenv -n upgrade_available)
|
||||
[ ${avail} -eq 0 ] && fw_setenv upgrade_available 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
REQUIRE_IMAGE_METADATA=1
|
||||
|
||||
senao_swap_active_fw() {
|
||||
swap_wap588m_active_fw() {
|
||||
echo "Doing swap active_fw" > /dev/console
|
||||
tmp_active_fw=$(fw_printenv | grep active_fw | awk -F= {'print $2'})
|
||||
if [ $tmp_active_fw == "0" ]; then
|
||||
@@ -12,6 +12,18 @@ senao_swap_active_fw() {
|
||||
fi
|
||||
}
|
||||
|
||||
senao_swap_active_fw() {
|
||||
echo "Doing swap active_fw" > /dev/console
|
||||
tmp_active_fw=$(fw_printenv -n active_fw)
|
||||
if [ $tmp_active_fw == "0" ]; then
|
||||
fw_setenv active_fw 1
|
||||
fw_setenv mtdparts nmbm0:1024k\(bl2\),512k\(u-boot-env\),2048k\(factory\),2048k\(fip\),112640k\(ubi_1\),112640k\(ubi\),384k\(cert\),640k\(userconfig\),384k\(crashdump\)
|
||||
else
|
||||
fw_setenv active_fw 0
|
||||
fw_setenv mtdparts nmbm0:1024k\(bl2\),512k\(u-boot-env\),2048k\(factory\),2048k\(fip\),112640k\(ubi\),112640k\(ubi_1\),384k\(cert\),640k\(userconfig\),384k\(crashdump\)
|
||||
fi
|
||||
}
|
||||
|
||||
platform_do_upgrade() {
|
||||
local board=$(board_name)
|
||||
|
||||
@@ -94,5 +106,8 @@ platform_post_upgrade_success() {
|
||||
senao,jeap6500)
|
||||
senao_swap_active_fw
|
||||
;;
|
||||
emplus,wap588m)
|
||||
swap_wap588m_active_fw
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ CONFIG_64BIT=y
|
||||
CONFIG_AHCI_MTK=y
|
||||
CONFIG_AIROHA_EN8801SC_PHY=y
|
||||
# CONFIG_AIROHA_EN8811H_PHY is not set
|
||||
# CONFIG_AIROHA_AN8801_PHY is not set
|
||||
CONFIG_AN8855_GSW=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
From 535fdc6dfce7def996a5188819ffc96231c36f98 Mon Sep 17 00:00:00 2001
|
||||
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
|
||||
Date: Tue, 2 Jan 2024 18:13:43 +0800
|
||||
Subject: [PATCH] [networking][999-2738-an8801sb-gphy-support.patch]
|
||||
|
||||
---
|
||||
drivers/net/phy/Kconfig | 5 +
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index ccd3f3f..5dbfb17 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -345,6 +345,11 @@ config SFP
|
||||
@@ -24,8 +12,6 @@ index ccd3f3f..5dbfb17 100644
|
||||
config AIROHA_EN8801SC_PHY
|
||||
tristate "Drivers for Airoha EN8801S Gigabit PHYs for MediaTek SoC."
|
||||
---help---
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index 1e8d67b..d39e54b 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -74,6 +74,7 @@ endif
|
||||
@@ -36,6 +22,64 @@ index 1e8d67b..d39e54b 100644
|
||||
obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
|
||||
air_en8811h-y := air_en8811h_main.o air_en8811h_api.o
|
||||
obj-$(CONFIG_AIROHA_EN8811H_PHY) += air_en8811h.o
|
||||
--
|
||||
2.18.0
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -870,12 +870,17 @@
|
||||
of_node_put(phy_node);
|
||||
|
||||
if (!phy_dev)
|
||||
- return -ENODEV;
|
||||
-
|
||||
+ {
|
||||
+ phylink_info(pl, "[phylink] reload phy-handle2. %s %d\n",__func__, __LINE__);
|
||||
+ phy_node = of_parse_phandle(dn, "phy-handle2", 0);
|
||||
+ phy_dev = of_phy_attach(pl->netdev, phy_node, flags, pl->link_interface);
|
||||
+ if (!phy_dev)
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface);
|
||||
if (ret)
|
||||
phy_detach(phy_dev);
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
|
||||
--- a/drivers/of/of_mdio.c
|
||||
+++ b/drivers/of/of_mdio.c
|
||||
@@ -226,7 +226,9 @@
|
||||
return rc;
|
||||
|
||||
/* Loop over the child nodes and register a phy_device for each phy */
|
||||
+ int an8801=0;
|
||||
for_each_available_child_of_node(np, child) {
|
||||
+ if(an8801==1)break;
|
||||
addr = of_mdio_parse_addr(&mdio->dev, child);
|
||||
if (addr < 0) {
|
||||
scanphys = true;
|
||||
@@ -234,7 +236,25 @@
|
||||
}
|
||||
|
||||
if (of_mdiobus_child_is_phy(child))
|
||||
+ {
|
||||
+ if(addr==30)
|
||||
+ {
|
||||
+ int phy_id ;
|
||||
+
|
||||
+ phy_id = mdiobus_read(mdio, addr, MII_PHYSID1) << 16 ;
|
||||
+ phy_id = phy_id + mdiobus_read(mdio, addr, MII_PHYSID2);
|
||||
+ dev_info(&mdio->dev, "[of_mdio] %s %d addr:%d phy_id:0x%x \n",__func__, __LINE__, addr, phy_id);
|
||||
+
|
||||
+ if (phy_id==0 || phy_id==0x1a750000)
|
||||
+ {
|
||||
+ dev_info(&mdio->dev, "[of_mdio] %s %d continue \n",__func__, __LINE__);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ an8801=1;
|
||||
+ }
|
||||
rc = of_mdiobus_register_phy(mdio, child, addr);
|
||||
+ }
|
||||
else
|
||||
rc = of_mdiobus_register_device(mdio, child, addr);
|
||||
|
||||
|
||||
@@ -493,10 +493,22 @@ define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/tools
|
||||
endef
|
||||
|
||||
|
||||
define Build/Install
|
||||
:
|
||||
endef
|
||||
|
||||
ifdef CONFIG_TARGET_PROFILE
|
||||
TARGET_PROFILE=$(subst ",,$(CONFIG_TARGET_PROFILE))
|
||||
PATCH_PROFILE_NAME=patches-$(subst DEVICE_,,$(TARGET_PROFILE))
|
||||
endif
|
||||
|
||||
define Build/Patch
|
||||
$(Build/Patch/Default)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_PROFILE_NAME)/,profile/)
|
||||
endef
|
||||
|
||||
|
||||
define Package/kmod-mt76/install
|
||||
true
|
||||
endef
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
Index: mt76-2024-04-03-1e336a85/mt7915/mt7915.h
|
||||
===================================================================
|
||||
--- mt76-2024-04-03-1e336a85.orig/mt7915/mt7915.h
|
||||
+++ mt76-2024-04-03-1e336a85/mt7915/mt7915.h
|
||||
@@ -71,8 +71,8 @@
|
||||
#define MT7915_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
|
||||
#define MT7915_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
|
||||
|
||||
-#define MT7915_THERMAL_THROTTLE_MAX 100
|
||||
-#define MT7915_CDEV_THROTTLE_MAX 99
|
||||
+#define MT7915_THERMAL_THROTTLE_MAX 80
|
||||
+#define MT7915_CDEV_THROTTLE_MAX 79
|
||||
|
||||
#define MT7915_SKU_RATE_NUM 161
|
||||
#define MT7915_SKU_PATH_NUM 185
|
||||
@@ -86,8 +86,8 @@
|
||||
|
||||
#define MT7915_CRIT_TEMP_IDX 0
|
||||
#define MT7915_MAX_TEMP_IDX 1
|
||||
-#define MT7915_CRIT_TEMP 110
|
||||
-#define MT7915_MAX_TEMP 120
|
||||
+#define MT7915_CRIT_TEMP 103
|
||||
+#define MT7915_MAX_TEMP 118
|
||||
|
||||
struct mt7915_vif;
|
||||
struct mt7915_sta;
|
||||
@@ -832,6 +832,13 @@ morse_hostapd_add_bss(){
|
||||
morse_override_hostapd_set_bss_options hostapd_cfg "$_phy" "$vif" || return 1
|
||||
json_get_vars wds wds_bridge sae_pwe dtim_period max_listen_int start_disabled
|
||||
|
||||
local network_config network_values
|
||||
json_get_values network_values network
|
||||
network_config=$(echo "$network_values" | cut -d' ' -f1)
|
||||
|
||||
if [ "$wds" -gt 0 ] && [ -z "$wds_bridge" ]; then
|
||||
wds_bridge="${network_config%%[0-9]*}"
|
||||
fi
|
||||
|
||||
raw_block=
|
||||
json_for_each_item morse_hostapd_add_raw raws
|
||||
|
||||
@@ -53,6 +53,11 @@ $(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for RAP750e_h
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-sonicfi-rap750e-s
|
||||
$(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for RAP750E-S
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-sonicfi-rap750w-311a
|
||||
$(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for RAP750W_311a
|
||||
@@ -78,6 +83,15 @@ $(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for AP72TIP-v4
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-zyxel-nwa130be
|
||||
$(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for NWA130BE
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-cig-wf672
|
||||
$(call Package/ath12k-wifi-default)
|
||||
TITLE:=board-2.bin for WF672
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-cig-wf189/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
|
||||
@@ -109,6 +123,15 @@ define Package/ath12k-wifi-sonicfi-rap750e-h/install
|
||||
$(INSTALL_DATA) ./ipq5332_qcn6432.regdb $(1)/lib/firmware/ath12k/QCN6432/hw1.0/regdb.bin
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-sonicfi-rap750e-s/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN6432/hw1.0/
|
||||
$(INSTALL_DATA) ./board-2.bin.rap750e_s.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin
|
||||
$(INSTALL_DATA) ./board-2.bin.rap750e_s.QCN6432 $(1)/lib/firmware/ath12k/QCN6432/hw1.0/board-2.bin
|
||||
# $(INSTALL_DATA) ./ipq5332_qcn6432.regdb $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/regdb.bin
|
||||
$(INSTALL_DATA) ./ipq5332_qcn6432.regdb $(1)/lib/firmware/ath12k/QCN6432/hw1.0/regdb.bin
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-sonicfi-rap750w-311a/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN6432/hw1.0/
|
||||
@@ -149,12 +172,29 @@ define Package/ath12k-wifi-sercomm-ap72tip-v4/install
|
||||
$(INSTALL_DATA) ./board-2.bin.ap72tip-v4.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-zyxel-nwa130be/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
|
||||
$(INSTALL_DATA) ./board-2.bin.nwa130be.QCN92XX $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/board-2.bin
|
||||
$(INSTALL_DATA) ./board-2.bin.nwa130be.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin
|
||||
endef
|
||||
|
||||
define Package/ath12k-wifi-cig-wf672/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
|
||||
$(INSTALL_DATA) ./board-2.bin.wf672.QCN92XX $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/board-2.bin
|
||||
$(INSTALL_DATA) ./board-2.bin.wf672.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ath12k-wifi-cig-wf189))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-edgecore-eap105))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sonicfi-rap7110c-341x))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sonicfi-rap750e-h))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sonicfi-rap750e-s))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sonicfi-rap750w-311a))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-cig-wf189w))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-cig-wf189h))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sercomm-ap72tip))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-sercomm-ap72tip-v4))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-zyxel-nwa130be))
|
||||
$(eval $(call BuildPackage,ath12k-wifi-cig-wf672))
|
||||
|
||||
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.nwa130be.IPQ5332
Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.nwa130be.IPQ5332
Normal file
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/rap7110c_341x-QCN92xx.bin → feeds/qca-wifi-7/ath12k-wifi/board-2.bin.nwa130be.QCN92XX
Executable file → Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/rap7110c_341x-QCN92xx.bin → feeds/qca-wifi-7/ath12k-wifi/board-2.bin.nwa130be.QCN92XX
Executable file → Normal file
Binary file not shown.
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap7110c_341x.QCN92XX
Normal file → Executable file
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap7110c_341x.QCN92XX
Normal file → Executable file
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/rap7110c_341x-IPQ5332.bin → feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap750e_s.IPQ5332
Executable file → Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/rap7110c_341x-IPQ5332.bin → feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap750e_s.IPQ5332
Executable file → Normal file
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap750e_s.QCN6432
Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.rap750e_s.QCN6432
Normal file
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.wf672.IPQ5332
Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.wf672.IPQ5332
Normal file
Binary file not shown.
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.wf672.QCN92XX
Normal file
BIN
feeds/qca-wifi-7/ath12k-wifi/board-2.bin.wf672.QCN92XX
Normal file
Binary file not shown.
25
feeds/qca-wifi-7/cig-platform-pkg/cig-poe-judgment/Makefile
Normal file
25
feeds/qca-wifi-7/cig-platform-pkg/cig-poe-judgment/Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=cig-poe-judgment
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/cig-poe-judgment
|
||||
SUBMENU:=Other modules
|
||||
TITLE:=CIG POE judgment
|
||||
FILES:=$(PKG_BUILD_DIR)/cig_poe_judgment.ko
|
||||
AUTOLOAD:=$(call AutoLoad,99,cig_poe_judgment)
|
||||
endef
|
||||
|
||||
define KernelPackage/cig-poe-judgment/description
|
||||
Find POE type
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,cig-poe-judgment))
|
||||
@@ -0,0 +1 @@
|
||||
obj-m += cig_poe_judgment.o
|
||||
@@ -0,0 +1,252 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define GPIO_MAX 8
|
||||
#define INT_MODE_MASK 0xf0
|
||||
#define DETECT_MODE1 0x3
|
||||
#define DETECT_MODE2 0x4
|
||||
|
||||
enum POE_TYPE {
|
||||
POE_TYPE_AT = 1,
|
||||
POE_TYPE_AF,
|
||||
POE_TYPE_BT,
|
||||
POE_TYPE_DC,
|
||||
POE_TYPE_MAX
|
||||
};
|
||||
|
||||
struct poe_irq_data
|
||||
{
|
||||
struct device *dev;
|
||||
int irq;
|
||||
struct tasklet_struct tasklet;
|
||||
int poe_type;
|
||||
};
|
||||
|
||||
static void *poe_gpio_base;
|
||||
static void *pse_gpio_base;
|
||||
struct poe_irq_data *data = NULL;
|
||||
u32 mode;
|
||||
|
||||
static const struct of_device_id my_of_ids[] = {
|
||||
{.compatible = "poe-judge"},
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of,my_of_ids);
|
||||
|
||||
static int poe_info_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
const char *type_str = "invalid";
|
||||
|
||||
switch (data->poe_type) {
|
||||
case POE_TYPE_AT:
|
||||
type_str = "AT";
|
||||
break;
|
||||
case POE_TYPE_AF:
|
||||
type_str = "AF";
|
||||
break;
|
||||
case POE_TYPE_BT:
|
||||
type_str = "BT";
|
||||
break;
|
||||
case POE_TYPE_DC:
|
||||
type_str = "DC";
|
||||
break;
|
||||
}
|
||||
|
||||
seq_printf(m, "%s\n", type_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void poe_tasklet_func(unsigned long data)
|
||||
{
|
||||
struct poe_irq_data *irq_data = (struct poe_irq_data *)data;
|
||||
|
||||
writel(0x3, pse_gpio_base+4);
|
||||
irq_data->poe_type = POE_TYPE_BT;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_key1_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct poe_irq_data *data = (struct poe_irq_data *)dev_id;
|
||||
|
||||
disable_irq_nosync(data->irq);
|
||||
tasklet_schedule(&data->tasklet);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int poe_info_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, poe_info_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct proc_ops poe_info_proc_fops = {
|
||||
.proc_open = poe_info_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
static int gpio_key_probe(struct platform_device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int irq = (-1);
|
||||
int val = 0;
|
||||
int gpio_id = 0;
|
||||
int gpio[GPIO_MAX] = {0}, gpio_val[GPIO_MAX] = {0};
|
||||
int num;
|
||||
char name[16];
|
||||
struct device_node *np = dev->dev.of_node;
|
||||
|
||||
if (of_property_read_u32(np, "detect-mode", &mode)) {
|
||||
pr_err("Failed to read detect mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = devm_kzalloc(&dev->dev, sizeof(struct poe_irq_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (mode & INT_MODE_MASK) {
|
||||
poe_gpio_base = ioremap(0x1017004, 8);
|
||||
pse_gpio_base = ioremap(0x1026000, 8);
|
||||
|
||||
writel(0x2c1, pse_gpio_base);
|
||||
writel(0x0, pse_gpio_base+4);
|
||||
|
||||
|
||||
data->dev = &dev->dev;
|
||||
dev_set_drvdata(&dev->dev, data);
|
||||
|
||||
gpio_id = of_get_named_gpio(dev->dev.of_node, "detect_gpio", 0);
|
||||
if (gpio_id < 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tasklet_init(&data->tasklet, poe_tasklet_func, (unsigned long)data);
|
||||
|
||||
ret = devm_gpio_request_one(&dev->dev, gpio_id, GPIOF_IN, "poe_judge");
|
||||
if(ret)
|
||||
{
|
||||
pr_err("GPIO23 request failed, ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl(poe_gpio_base);
|
||||
if(val == 1)
|
||||
{
|
||||
pr_info("poe type is af or bt,close pse first\n");
|
||||
data->poe_type = POE_TYPE_AF;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->poe_type = POE_TYPE_AT;
|
||||
}
|
||||
|
||||
irq = gpio_to_irq(gpio_id);
|
||||
data->irq = irq;
|
||||
|
||||
ret = devm_request_any_context_irq(&dev->dev, data->irq,
|
||||
gpio_key1_irq_handler,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
"poe_judge", data);
|
||||
if (ret)
|
||||
{
|
||||
pr_err("Request irq fail %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
if (mode == DETECT_MODE1 || mode == DETECT_MODE2) {
|
||||
num = 3;
|
||||
} else {
|
||||
pr_err("Wrong poe detect mode\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
sprintf(name, "detect-gpio%d", i+1);
|
||||
gpio[i] = of_get_named_gpio(np, name, 0);
|
||||
ret = gpio_request(gpio[i], name);
|
||||
if (ret) {
|
||||
pr_err("Can not request gpio %d\n", i+1);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_input(gpio[i]);
|
||||
gpio_val[i] = gpio_get_value_cansleep(gpio[i]);
|
||||
}
|
||||
|
||||
if (mode == DETECT_MODE1){
|
||||
if (gpio_val[0] > 0) {
|
||||
data->poe_type = POE_TYPE_DC;
|
||||
} else if (gpio_val[1] > 0){
|
||||
if (gpio_val[2] == 0) {
|
||||
data->poe_type = POE_TYPE_AT;
|
||||
} else {
|
||||
data->poe_type = POE_TYPE_AF;
|
||||
}
|
||||
}
|
||||
}else if (mode == DETECT_MODE2){
|
||||
switch (gpio_val[0] | (gpio_val[1] << 1) | (gpio_val[2] << 2)) {
|
||||
case 3:
|
||||
data->poe_type = POE_TYPE_AT;
|
||||
break;
|
||||
case 4:
|
||||
data->poe_type = POE_TYPE_BT;
|
||||
break;
|
||||
case 7:
|
||||
data->poe_type = POE_TYPE_AF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!proc_create("poe_info", 0444, NULL, &poe_info_proc_fops)) {
|
||||
pr_err("Failed to create proc entry for poe_info\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_key_remove(struct platform_device *dev)
|
||||
{
|
||||
remove_proc_entry("poe_info", NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver poe_judge_driver =
|
||||
{
|
||||
.driver = {
|
||||
.name = "poe_judge",
|
||||
.of_match_table = my_of_ids,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = gpio_key_probe,
|
||||
.remove = gpio_key_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(poe_judge_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Poe type judgment driver");
|
||||
MODULE_AUTHOR("huangyunxiang<huangyunxiang@cigtech.com>");
|
||||
30
feeds/qca-wifi-7/cig-platform-pkg/cig-wifi-mode-sw/Makefile
Normal file
30
feeds/qca-wifi-7/cig-platform-pkg/cig-wifi-mode-sw/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=cig-wifi-mode-switch
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/cig-wifi-mode-sw
|
||||
SUBMENU:=Other modules
|
||||
TITLE:=CIG wifi mode switch tool
|
||||
FILES:=$(PKG_BUILD_DIR)/cig_rf_switch.ko
|
||||
AUTOLOAD:=$(call AutoLoad,60,cig_rf_switch)
|
||||
endef
|
||||
|
||||
define KernelPackage/cig-wifi-mode-sw/description
|
||||
CIG wifi mode switch tool for configure wifi mode 2 bands or 3 bands
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules
|
||||
endef
|
||||
|
||||
define KernelPackage/cig-wifi-mode-sw/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin/
|
||||
$(INSTALL_BIN) ./files/cig_wifi_mode_sw $(1)/usr/sbin/cig_wms
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,cig-wifi-mode-sw))
|
||||
11
feeds/qca-wifi-7/cig-platform-pkg/cig-wifi-mode-sw/files/cig_wifi_mode_sw
Executable file
11
feeds/qca-wifi-7/cig-platform-pkg/cig-wifi-mode-sw/files/cig_wifi_mode_sw
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
band=$1
|
||||
if [ $band -eq 2 ] || [ $band -eq 3 ]; then
|
||||
echo $band > /proc/rf_switch
|
||||
echo "reboot for switch wifi mode 2/3 bands"
|
||||
sleep 1
|
||||
reboot
|
||||
else
|
||||
echo "error band param"
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
obj-m += cig_rf_switch.o
|
||||
@@ -0,0 +1,276 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
||||
#define PROC_NAME "rf_switch"
|
||||
#define PARTITION_NAME "RF_SWITCH"
|
||||
#define MAX_DATA_SIZE 2
|
||||
#define MAX_MMC_DEVICE 2
|
||||
|
||||
struct block_device *target_bdev = NULL;
|
||||
static char current_value[MAX_DATA_SIZE] = "3";
|
||||
|
||||
static unsigned int __blkdev_sectors_to_bio_pages(sector_t nr_sects)
|
||||
{
|
||||
sector_t pages = DIV_ROUND_UP_SECTOR_T(nr_sects, PAGE_SIZE / 512);
|
||||
|
||||
return min(pages, (sector_t)BIO_MAX_VECS);
|
||||
}
|
||||
|
||||
struct block_device *find_mmc_partition(void)
|
||||
{
|
||||
struct gendisk *disk = NULL;
|
||||
unsigned long idx;
|
||||
struct block_device *bdev = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_MMC_DEVICE; i++) {
|
||||
bdev = blkdev_get_by_dev(MKDEV(MMC_BLOCK_MAJOR, i * CONFIG_MMC_BLOCK_MINORS), FMODE_READ | FMODE_WRITE, NULL);
|
||||
if (IS_ERR(bdev)) {
|
||||
pr_err("Failed to open MMC device %u: %ld\n", i, PTR_ERR(bdev));
|
||||
continue;
|
||||
}
|
||||
|
||||
disk = bdev->bd_disk;
|
||||
if (!disk) {
|
||||
blkdev_put(bdev, FMODE_READ | FMODE_WRITE);
|
||||
continue;
|
||||
}
|
||||
|
||||
xa_for_each_start(&disk->part_tbl, idx, bdev, 1) {
|
||||
if (bdev->bd_meta_info && strcmp(bdev->bd_meta_info->volname, PARTITION_NAME) == 0) {
|
||||
pr_info("Found RF_SWITCH partition at device %u\n", i);
|
||||
return bdev;
|
||||
}
|
||||
}
|
||||
|
||||
blkdev_put(bdev, FMODE_READ | FMODE_WRITE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int read_string_from_emmc(struct block_device *bdev, size_t max_length, char *buffer)
|
||||
{
|
||||
struct bio *bio;
|
||||
struct page *page;
|
||||
int err = 0;
|
||||
void *data;
|
||||
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
if (!page) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bio = bio_alloc(bdev, __blkdev_sectors_to_bio_pages(1), REQ_OP_READ, GFP_KERNEL);
|
||||
bio_set_dev(bio, bdev);
|
||||
bio->bi_iter.bi_sector = 0;
|
||||
bio_add_page(bio, page, PAGE_SIZE, 0);
|
||||
|
||||
submit_bio_wait(bio);
|
||||
|
||||
if (bio->bi_status) {
|
||||
err = -EIO;
|
||||
goto out_bio;
|
||||
}
|
||||
|
||||
data = kmap(page);
|
||||
kunmap(page);
|
||||
memcpy(buffer, data, max_length - 1);
|
||||
buffer[max_length - 1] = '\0';
|
||||
|
||||
out_bio:
|
||||
bio_put(bio);
|
||||
__free_page(page);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rf_switch_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
char buffer[MAX_DATA_SIZE] = {0};
|
||||
int ret;
|
||||
|
||||
ret = read_string_from_emmc(target_bdev, MAX_DATA_SIZE, buffer);
|
||||
if (ret) {
|
||||
seq_printf(m, "%s\n", current_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(buffer, "2") == 0 || strcmp(buffer, "3") == 0) {
|
||||
strncpy(current_value, buffer, MAX_DATA_SIZE);
|
||||
seq_printf(m, "%s\n", current_value);
|
||||
} else {
|
||||
seq_printf(m, "%s\n", current_value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blkdev_issue_write(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, struct page *page)
|
||||
{
|
||||
int ret = 0;
|
||||
sector_t bs_mask;
|
||||
struct bio *bio;
|
||||
|
||||
int bi_size = 0;
|
||||
unsigned int sz;
|
||||
|
||||
if (bdev_read_only(bdev))
|
||||
return -EPERM;
|
||||
|
||||
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
|
||||
if ((sector | nr_sects) & bs_mask)
|
||||
return -EINVAL;
|
||||
|
||||
bio = bio_alloc(bdev, __blkdev_sectors_to_bio_pages(nr_sects),
|
||||
REQ_OP_WRITE, gfp_mask);
|
||||
if (!bio) {
|
||||
pr_err("Couldn't alloc bio");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
sz = bdev_logical_block_size(bdev);
|
||||
bi_size = bio_add_page(bio, page, sz, 0);
|
||||
|
||||
if(bi_size != sz) {
|
||||
pr_err("Couldn't add page to the log block");
|
||||
goto error;
|
||||
}
|
||||
if (bio)
|
||||
{
|
||||
ret = submit_bio_wait(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
error:
|
||||
bio_put(bio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int write_data_to_emmc(struct block_device *bdev, const unsigned char *data, unsigned char fill_byte)
|
||||
{
|
||||
struct page *page;
|
||||
void *ptr;
|
||||
sector_t sector_offset = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!bdev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
if (!page) {
|
||||
pr_err("Failed to allocate page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ptr = kmap_atomic(page);
|
||||
|
||||
memcpy(ptr, data, MAX_DATA_SIZE);
|
||||
|
||||
memset(ptr + MAX_DATA_SIZE, fill_byte, 512-MAX_DATA_SIZE);
|
||||
kunmap_atomic(ptr);
|
||||
|
||||
ret = blkdev_issue_write(bdev, sector_offset , 1 ,GFP_ATOMIC, page);
|
||||
if (ret) {
|
||||
pr_err("Failed to write to eMMC at offset 0: %d\n", ret);
|
||||
__free_page(page);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sync_blockdev(bdev);
|
||||
__free_page(page);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t rf_switch_proc_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned char buffer[MAX_DATA_SIZE] = {0};
|
||||
int ret;
|
||||
|
||||
if (count != MAX_DATA_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(buffer, user_buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
buffer[count -1] = '\0';
|
||||
|
||||
if (strcmp(buffer, "2") != 0 && strcmp(buffer, "3") != 0) {
|
||||
pr_err("Invalid value: %s. Only '2' or '3' are allowed.\n", buffer);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = write_data_to_emmc(target_bdev, buffer, 0xFF);
|
||||
if (ret) {
|
||||
pr_err("Failed to write to RF_SWITCH\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
strncpy(current_value, buffer, MAX_DATA_SIZE);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int rf_switch_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, rf_switch_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct proc_ops rf_switch_proc_fops = {
|
||||
.proc_open = rf_switch_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_write = rf_switch_proc_write,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
static int __init rf_switch_init(void)
|
||||
{
|
||||
target_bdev = find_mmc_partition();
|
||||
if (!target_bdev) {
|
||||
pr_err("Failed to find eMMC card or RF_SWITCH partition\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!proc_create(PROC_NAME, 0666, NULL, &rf_switch_proc_fops)) {
|
||||
pr_err("Failed to create proc entry\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pr_info("RF_SWITCH partition proc interface created\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rf_switch_exit(void)
|
||||
{
|
||||
if (target_bdev) {
|
||||
blkdev_put(target_bdev, FMODE_READ | FMODE_WRITE);
|
||||
target_bdev = NULL;
|
||||
}
|
||||
remove_proc_entry(PROC_NAME, NULL);
|
||||
pr_info("RF_SWITCH partition proc interface removed\n");
|
||||
}
|
||||
|
||||
module_init(rf_switch_init);
|
||||
module_exit(rf_switch_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Yunxiang Huang");
|
||||
MODULE_DESCRIPTION("RF_SWITCH partition read/write driver");
|
||||
@@ -121,8 +121,6 @@ hostapd_common_add_device_config() {
|
||||
config_add_boolean legacy_rates
|
||||
config_add_int cell_density
|
||||
config_add_int rts_threshold
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
config_add_int maxassoc
|
||||
config_add_int reg_power_type
|
||||
config_add_boolean stationary_ap
|
||||
@@ -147,7 +145,7 @@ hostapd_prepare_device_config() {
|
||||
|
||||
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
|
||||
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
|
||||
rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
|
||||
rts_threshold beacon_rate maxassoc \
|
||||
rnr_beacon mbssid:0 band reg_power_type stationary_ap acs_exclude_dfs\
|
||||
maxassoc_ignore_probe band
|
||||
|
||||
@@ -244,8 +242,6 @@ hostapd_prepare_device_config() {
|
||||
hostapd_add_rate brlist "$br"
|
||||
done
|
||||
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
|
||||
[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
|
||||
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
|
||||
@@ -427,6 +423,9 @@ hostapd_common_add_bss_config() {
|
||||
|
||||
config_add_boolean apup
|
||||
config_add_string apup_peer_ifname_prefix
|
||||
|
||||
config_add_int rssi_reject_assoc_rssi
|
||||
config_add_int rssi_ignore_probe_request
|
||||
}
|
||||
|
||||
hostapd_set_vlan_file() {
|
||||
@@ -680,7 +679,8 @@ hostapd_set_bss_options() {
|
||||
ppsk airtime_bss_weight airtime_bss_limit airtime_sta_weight \
|
||||
multicast_to_unicast_all proxy_arp per_sta_vif \
|
||||
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id radius_server_clients radius_server_auth_port \
|
||||
vendor_elements fils ocv apup uci_section dynamic_probe_resp multi_psk
|
||||
vendor_elements fils ocv apup uci_section dynamic_probe_resp multi_psk \
|
||||
rssi_reject_assoc_rssi rssi_ignore_probe_request
|
||||
|
||||
set_default fils 0
|
||||
set_default isolate 0
|
||||
@@ -737,6 +737,8 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
|
||||
append bss_conf "utf8_ssid=$utf8_ssid" "$N"
|
||||
append bss_conf "multi_ap=$multi_ap" "$N"
|
||||
[ -n "$rssi_reject_assoc_rssi" ] && append bss_conf "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
|
||||
[ -n "$rssi_ignore_probe_request" ] && append bss_conf "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
|
||||
[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
|
||||
|
||||
[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
|
||||
@@ -775,11 +777,16 @@ hostapd_set_bss_options() {
|
||||
set_default sae_require_mfp 1
|
||||
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
|
||||
;;
|
||||
psk-sae|psk2-radius|eap-eap2)
|
||||
psk-sae|eap-eap2)
|
||||
set_default ieee80211w 1
|
||||
set_default sae_require_mfp 1
|
||||
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
|
||||
;;
|
||||
psk2-radius)
|
||||
set_default ieee80211w 1
|
||||
set_default sae_require_mfp 0
|
||||
[ "$ppsk" -eq 0 ] && set_default sae_pwe 4
|
||||
;;
|
||||
esac
|
||||
[ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N"
|
||||
[ -n "$sae_pwe" ] && append bss_conf "sae_pwe=$sae_pwe" "$N"
|
||||
|
||||
@@ -144,7 +144,7 @@ function netifd_reload() {
|
||||
|
||||
push(ssid.interfaces, iface.ifname);
|
||||
ssid.bands[band] = iface.ifname;
|
||||
ssid.mpsk = config.multi_psk;
|
||||
ssid.mpsk = ssid?.mpsk ? true : config.multi_psk;
|
||||
for (let sta in iface.stations) {
|
||||
let stacfg = sta.config;
|
||||
|
||||
@@ -308,18 +308,18 @@ function sta_auth_cache(ifname, addr, idx, phrase) {
|
||||
function auth_cb(msg) {
|
||||
let data = msg.data;
|
||||
|
||||
if (!is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
|
||||
printf(`Event ${msg.type}: ${msg.data}\n`);
|
||||
switch (msg.type) {
|
||||
case 'sta_auth':
|
||||
if (!is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
|
||||
return {
|
||||
psk: sta_auth_psk(data.iface, data.sta),
|
||||
force_psk: true,
|
||||
};
|
||||
case 'sta_connected':
|
||||
if (data.psk_idx == null)
|
||||
if (data.psk_idx == null || !is_ssid_mpsk(data.iface))
|
||||
return;
|
||||
return sta_auth_cache(data.iface, data.sta, data.psk_idx, data.psk);
|
||||
case 'reload':
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -934,8 +934,10 @@ void handle_probe_req(struct hostapd_dat
|
||||
int ubus_response;
|
||||
|
||||
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
|
||||
- ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
||||
+ ssi_signal < hapd->iconf->rssi_ignore_probe_request) {
|
||||
+ hostapd_ubus_notify_rssi(hapd, "rssi-ignore-probe", mgmt->sa, ssi_signal);
|
||||
return;
|
||||
+ }
|
||||
|
||||
if (len < IEEE80211_HDRLEN)
|
||||
return;
|
||||
@@ -1,3 +1,4 @@
|
||||
unchanged:
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3003,6 +3003,8 @@ static int hostapd_config_fill(struct ho
|
||||
@@ -9,12 +10,10 @@
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
#ifndef CONFIG_NO_CTRL_IFACE
|
||||
} else if (os_strcmp(buf, "ctrl_interface") == 0) {
|
||||
@@ -4958,8 +4960,22 @@ int hostapd_set_iface(struct hostapd_con
|
||||
return -1;
|
||||
}
|
||||
@@ -4982,6 +4982,19 @@ struct hostapd_config * hostapd_config_r
|
||||
fclose(f);
|
||||
|
||||
- for (i = 0; i < conf->num_bss; i++)
|
||||
+ for (i = 0; i < conf->num_bss; i++) {
|
||||
for (i = 0; i < conf->num_bss; i++) {
|
||||
+ if (*conf->bss[i]->ft_key) {
|
||||
+ u8 buffer[128];
|
||||
+ sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X %02X%02X%02X%02X%02X%02X %s", MAC2STR(conf->bss[i]->bssid), MAC2STR(conf->bss[i]->bssid), conf->bss[i]->ft_key);
|
||||
@@ -25,14 +24,12 @@
|
||||
+ add_r0kh(conf->bss[i], buffer);
|
||||
+ sprintf(buffer, "00:00:00:00:00:00 00:00:00:00:00:00 %s", conf->bss[i]->ft_key);
|
||||
+ add_r1kh(conf->bss[i], buffer);
|
||||
+ hexstr2bin(conf->bss[i]->bssid, conf->bss[i]->r1_key_holder, FT_R1KH_ID_LEN);
|
||||
+ hexstr2bin(conf->bss[i]->bssid, conf->bss[i]->r1_key_holder, FT_R1KH_ID_LEN);
|
||||
+ conf->bss[i]->r0_key_holder_bssid = 1;
|
||||
+ }
|
||||
hostapd_set_security_params(conf->bss[i], 0);
|
||||
+ }
|
||||
|
||||
if (hostapd_config_check(conf, 0)) {
|
||||
wpa_printf(MSG_ERROR, "Configuration check failed");
|
||||
hostapd_set_security_params(conf->bss[i], 1);
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (conf->ieee80211be && conf->bss[i]->ieee80211w > 0
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -398,6 +398,7 @@ struct hostapd_bss_config {
|
||||
|
||||
@@ -1923,6 +1923,21 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
return;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "address", addr);
|
||||
blobmsg_add_u32(&b, "rssi", rssi);
|
||||
|
||||
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
|
||||
}
|
||||
|
||||
void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq)
|
||||
{
|
||||
if (!hapd->ubus.obj.has_subscribers)
|
||||
|
||||
@@ -56,6 +56,7 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
|
||||
size_t len);
|
||||
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
|
||||
int chan_width, int cf1, int cf2);
|
||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi);
|
||||
|
||||
void hostapd_ubus_notify_bss_transition_response(
|
||||
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
|
||||
|
||||
@@ -785,6 +785,7 @@ int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
struct hostapd_sta_wpa_psk_short *psk = sta->psk;
|
||||
char addr[sizeof(MACSTR)];
|
||||
uc_value_t *val, *cur;
|
||||
int ret = 0;
|
||||
@@ -801,6 +802,8 @@ void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta
|
||||
val = ucv_object_new(vm);
|
||||
if (sta->psk_idx)
|
||||
ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1));
|
||||
if (sta->psk)
|
||||
ucv_object_add(val, "psk", ucv_string_new(sta->psk->passphrase));
|
||||
uc_value_push(ucv_get(val));
|
||||
|
||||
val = wpa_ucode_call(3);
|
||||
|
||||
@@ -15,6 +15,7 @@ sercomm,ap72tip)
|
||||
;;
|
||||
sonicfi,rap7110c-341x|\
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s|\
|
||||
sonicfi,rap750w-311a)
|
||||
ucidef_set_led_default "power" "POWER" "pwm:blue" "on"
|
||||
;;
|
||||
|
||||
@@ -13,13 +13,15 @@ ipq53xx_setup_interfaces()
|
||||
ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4 eth5" "eth0"
|
||||
;;
|
||||
cig,wf189|\
|
||||
cig,wf672|\
|
||||
edgecore,eap105|\
|
||||
sercomm,ap72tip|\
|
||||
sonicfi,rap750w-311a)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
sonicfi,rap7110c-341x|\
|
||||
sonicfi,rap750e-h)
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s)
|
||||
ucidef_set_interfaces_lan_wan "" "eth0"
|
||||
;;
|
||||
cig,wf189w)
|
||||
@@ -33,6 +35,9 @@ ipq53xx_setup_interfaces()
|
||||
sercomm,ap72tip-v4)
|
||||
ucidef_set_interface_wan "eth0"
|
||||
;;
|
||||
zyxel,nwa130be)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -40,21 +45,35 @@ qcom_setup_macs()
|
||||
{
|
||||
local board="$1"
|
||||
case $board in
|
||||
cig,wf189w|\
|
||||
cig,wf189h|\
|
||||
cig,wf189w|\
|
||||
cig,wf189h|\
|
||||
cig,wf189)
|
||||
mtd=$(find_mtd_chardev "0:APPSBLENV")
|
||||
[ -z "$mtd" ] && return;
|
||||
mac=$(grep eth1addr= $mtd | cut -d= -f2)
|
||||
mtd=$(find_mtd_chardev "0:APPSBLENV")
|
||||
[ -z "$mtd" ] && return;
|
||||
mac=$(grep eth1addr= $mtd | cut -d= -f2)
|
||||
[ -z "$mac" ] && return;
|
||||
wan_mac=$(macaddr_canonicalize $mac)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
ucidef_set_network_device_mac eth0 $wan_mac
|
||||
ucidef_set_network_device_mac eth1 $lan_mac
|
||||
ucidef_set_label_macaddr $wan_mac
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
|
||||
;;
|
||||
cig,wf672)
|
||||
mmc=$(find_mmc_part "0:APPSBLENV")
|
||||
[ -z "$mmc" ] && return;
|
||||
mac=$(grep eth1addr= $mmc | cut -d= -f2)
|
||||
[ -z "$mac" ] && return;
|
||||
wan_mac=$(macaddr_canonicalize $mac)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
ucidef_set_network_device_mac eth0 $wan_mac
|
||||
ucidef_set_network_device_mac eth1 $lan_mac
|
||||
ucidef_set_label_macaddr $wan_mac
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
|
||||
;;
|
||||
sercomm,ap72tip)
|
||||
wan_mac=$(cat /sys/class/net/eth0/address)
|
||||
@@ -66,13 +85,17 @@ qcom_setup_macs()
|
||||
edgecore,eap105)
|
||||
wan_mac=$(cat /sys/class/net/eth0/address)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
|
||||
;;
|
||||
sonicfi,rap7110c-341x|\
|
||||
sonicfi,rap750e-h)
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s)
|
||||
wan_mac=$(cat /sys/class/net/eth0/address)
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 1)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 2)
|
||||
[ "$board" = "sonicfi,rap7110c-34x" ] &&
|
||||
[ "$board" = "sonicfi,rap7110c-341x" ] &&
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 3)
|
||||
;;
|
||||
sonicfi,rap750w-311a)
|
||||
@@ -87,6 +110,19 @@ qcom_setup_macs()
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 3)
|
||||
;;
|
||||
zyxel,nwa130be)
|
||||
wan_mac=$(cat /proc/cmdline)
|
||||
wan_mac="${wan_mac##*hwaddr=}"
|
||||
wan_mac="${wan_mac%% *}"
|
||||
wan_mac="$(echo ${wan_mac} | sed 's/\(..\)/\1:/g;s/:$//')"
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
ucidef_set_network_device_mac eth0 $wan_mac
|
||||
ucidef_set_network_device_mac eth1 $lan_mac
|
||||
ucidef_set_label_macaddr $wan_mac
|
||||
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
|
||||
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
|
||||
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
|
||||
;;
|
||||
*)
|
||||
wan_mac=$(cat /sys/class/net/eth1/address)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
|
||||
@@ -23,6 +23,39 @@ caldata_extract() {
|
||||
caldata_die "failed to extract calibration data from $mtd"
|
||||
}
|
||||
|
||||
cig_ipq5322_cal() {
|
||||
local ext_ant=0
|
||||
|
||||
[ -f /sys/firmware/devicetree/base/soc@0/wifi@c0000000/ext_antenna ] && ext_ant=1
|
||||
|
||||
if [ "$ext_ant" = "0" ]; then
|
||||
caldata_extract_mmc "0:ART" 0x1000 0x20000
|
||||
else
|
||||
caldata_extract_mmc "0:ART" 0xbd800 0x20000
|
||||
fi
|
||||
}
|
||||
|
||||
cig_qcn92xx_cal() {
|
||||
local bands=$(cat /proc/rf_switch)
|
||||
local ext_ant=0
|
||||
|
||||
[ -f /sys/firmware/devicetree/base/soc@0/wifi@c0000000/ext_antenna ] && ext_ant=1
|
||||
|
||||
if [ "$bands" = "2" ]; then
|
||||
if [ "$ext_ant" = "0" ]; then
|
||||
caldata_extract_mmc "0:ART" 0x8b800 0x2d000
|
||||
else
|
||||
caldata_extract_mmc "0:ART" 0xe3000 0x2d000
|
||||
fi
|
||||
else
|
||||
if [ "$ext_ant" = "0" ]; then
|
||||
caldata_extract_mmc "0:ART" 0x58800 0x2d000
|
||||
else
|
||||
caldata_extract_mmc "0:ART" 0x115000 0x2d000
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
board=$(board_name)
|
||||
case "$FIRMWARE" in
|
||||
ath12k/IPQ5332/hw1.0/caldata.bin)
|
||||
@@ -32,13 +65,18 @@ ath12k/IPQ5332/hw1.0/caldata.bin)
|
||||
cig,wf189|\
|
||||
edgecore,eap105|\
|
||||
sercomm,ap72tip-v4|\
|
||||
sercomm,ap72tip)
|
||||
sercomm,ap72tip|\
|
||||
zyxel,nwa130be)
|
||||
caldata_extract "0:ART" 0x1000 0x20000
|
||||
;;
|
||||
cig,wf672)
|
||||
cig_ipq5322_cal
|
||||
;;
|
||||
sonicfi,rap7110c-341x)
|
||||
caldata_extract_mmc "0:ART" 0x1000 0xF800
|
||||
;;
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s|\
|
||||
sonicfi,rap750w-311a)
|
||||
caldata_extract "0:ART" 0x1000 0xf800
|
||||
;;
|
||||
@@ -49,9 +87,13 @@ ath12k/QCN92XX/hw1.0/cal-pci-0001:01:00.0.bin)
|
||||
cig,wf189|\
|
||||
edgecore,eap105|\
|
||||
sercomm,ap72tip-v4|\
|
||||
sercomm,ap72tip)
|
||||
sercomm,ap72tip|\
|
||||
zyxel,nwa130be)
|
||||
caldata_extract "0:ART" 0x58800 0x2d000
|
||||
;;
|
||||
cig,wf672)
|
||||
cig_qcn92xx_cal
|
||||
;;
|
||||
sonicfi,rap7110c-341x)
|
||||
caldata_extract_mmc "0:ART" 0x58800 0x2d000
|
||||
;;
|
||||
@@ -60,6 +102,7 @@ ath12k/QCN92XX/hw1.0/cal-pci-0001:01:00.0.bin)
|
||||
ath12k/QCN6432/hw1.0/caldata_1.bin)
|
||||
case "$board" in
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s|\
|
||||
sonicfi,rap750w-311a)
|
||||
caldata_extract "0:ART" 0x12800 0x18800
|
||||
;;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# /etc/hotplug.d/iface/85-greqos
|
||||
[ "$ACTION" == "ifup" ] || exit 0
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
case "$(board_name)" in
|
||||
cig,wf189|\
|
||||
cig,wf189w|\
|
||||
cig,wf189h|\
|
||||
cig,wf672)
|
||||
case "$INTERFACE" in
|
||||
gre*)
|
||||
dev=$(ubus call network.interface.$INTERFACE status | jsonfilter -e '@.l3_device')
|
||||
[ -n "$dev" ] && {
|
||||
tc qdisc del dev $dev root 2>/dev/null
|
||||
tc qdisc add dev $dev root noqueue
|
||||
}
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
22
feeds/qca-wifi-7/ipq53xx/base-files/etc/init.d/phy_quirks
Executable file
22
feeds/qca-wifi-7/ipq53xx/base-files/etc/init.d/phy_quirks
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
|
||||
boot() {
|
||||
. /lib/functions.sh
|
||||
|
||||
case "$(board_name)" in
|
||||
edgecore,eap105)
|
||||
ssdk_sh debug phy set 0x1 0x601FD032 0xff
|
||||
;;
|
||||
zyxel,nwa130be)
|
||||
#eth0: APPE: phyaddr 4 green:2.5G orange:others
|
||||
ssdk_sh debug phy set 4 0x40078074 0x670
|
||||
ssdk_sh debug phy set 4 0x40078078 0x8600
|
||||
|
||||
#eth1: MHT: phyaddr 3 green:2.5G orange:others
|
||||
ssdk_sh debug phy set 3 0x40078074 0x670
|
||||
ssdk_sh debug phy set 3 0x40078078 0x8600
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -57,6 +57,52 @@ sonicfi_dualimage_check() {
|
||||
fi
|
||||
}
|
||||
|
||||
spi_nor_emmc_do_upgrade_bootconfig() {
|
||||
local tar_file="$1"
|
||||
|
||||
local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
|
||||
board_dir=${board_dir%/}
|
||||
[ -f /proc/boot_info/bootconfig0/getbinary_bootconfig ] || {
|
||||
echo "bootconfig does not exist"
|
||||
exit
|
||||
}
|
||||
CI_ROOTPART="$(cat /proc/boot_info/bootconfig0/rootfs/upgradepartition)"
|
||||
CI_KERNPART="$(cat /proc/boot_info/bootconfig0/0:HLOS/upgradepartition)"
|
||||
|
||||
[ -n "$CI_KERNPART" -a -n "$CI_ROOTPART" ] || {
|
||||
echo "kernel or rootfs partition is unknown"
|
||||
exit
|
||||
}
|
||||
|
||||
local primary="0"
|
||||
[ "$(cat /proc/boot_info/bootconfig0/rootfs/primaryboot)" = "0" ] && primary="1"
|
||||
echo "$primary" > /proc/boot_info/bootconfig0/rootfs/primaryboot 2>/dev/null
|
||||
echo "$primary" > /proc/boot_info/bootconfig0/0:HLOS/primaryboot 2>/dev/null
|
||||
cp /proc/boot_info/bootconfig0/getbinary_bootconfig /tmp/bootconfig
|
||||
|
||||
do_flash_emmc $tar_file $CI_KERNPART $board_dir kernel
|
||||
do_flash_emmc $tar_file $CI_ROOTPART $board_dir root
|
||||
|
||||
local emmcblock="$(find_mmc_part "rootfs_data")"
|
||||
if [ -e "$emmcblock" ]; then
|
||||
mkfs.ext4 -F "$emmcblock"
|
||||
fi
|
||||
|
||||
for part in "0:BOOTCONFIG" "0:BOOTCONFIG1"; do
|
||||
local mtdchar=$(echo $(find_mtd_chardev $part) | sed 's/^.\{5\}//')
|
||||
if [ -n "$mtdchar" ]; then
|
||||
echo start to update $mtdchar
|
||||
mtd -qq write /proc/boot_info/bootconfig0/getbinary_bootconfig "/dev/${mtdchar}" 2>/dev/null && echo update mtd $mtdchar
|
||||
else
|
||||
emmcblock=$(find_mmc_part $part)
|
||||
echo erase ${emmcblock}
|
||||
dd if=/dev/zero of=${emmcblock} 2> /dev/null
|
||||
echo update $emmcblock
|
||||
dd if=/tmp/bootconfig of=${emmcblock} 2> /dev/null
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
emmc_do_upgrade() {
|
||||
local tar_file="$1"
|
||||
local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
|
||||
@@ -86,6 +132,8 @@ platform_do_upgrade() {
|
||||
|
||||
board=$(board_name)
|
||||
case $board in
|
||||
sercomm,ap72tip-v4|\
|
||||
sercomm,ap72tip|\
|
||||
cig,wf189w|\
|
||||
cig,wf189h|\
|
||||
cig,wf189)
|
||||
@@ -98,6 +146,9 @@ platform_do_upgrade() {
|
||||
fi
|
||||
nand_upgrade_tar "$1"
|
||||
;;
|
||||
cig,wf672)
|
||||
spi_nor_emmc_do_upgrade_bootconfig $1
|
||||
;;
|
||||
edgecore,eap105)
|
||||
if [ "$(find_mtd_chardev rootfs)" ]; then
|
||||
CI_UBIPART="rootfs"
|
||||
@@ -117,12 +168,12 @@ platform_do_upgrade() {
|
||||
emmc_do_upgrade "$1"
|
||||
;;
|
||||
sonicfi,rap750e-h|\
|
||||
sonicfi,rap750e-s|\
|
||||
sonicfi,rap750w-311a)
|
||||
sonicfi_dualimage_check
|
||||
nand_upgrade_tar "$1"
|
||||
;;
|
||||
sercomm,ap72tip-v4|\
|
||||
sercomm,ap72tip)
|
||||
zyxel,nwa130be)
|
||||
nand_upgrade_tar "$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1223,3 +1223,5 @@ CONFIG_PSTORE=y
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
CONFIG_PSTORE_PMSG=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
# CONFIG_RTL8221D_PHY is not set
|
||||
# CONFIG_INPUT_LSM303AGR is not set
|
||||
|
||||
@@ -18,6 +18,21 @@
|
||||
model = "CIG WF189";
|
||||
compatible = "cig,wf189", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332-rdp468", "qcom,ipq5332";
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
ramoops@49c00000 {
|
||||
compatible = "ramoops";
|
||||
no-map;
|
||||
reg = <0x0 0x49c00000 0x0 0x50000>;
|
||||
record-size = <0x20000>;
|
||||
console-size = <0x8000>;
|
||||
pmsg-size = <0x8000>;
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart0;
|
||||
serial1 = &blsp1_uart1;
|
||||
@@ -221,6 +236,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
poe {
|
||||
compatible = "poe-judge";
|
||||
detect-mode = <0x3>;
|
||||
detect-gpio1 = <&tlmm 25 GPIO_ACTIVE_HIGH>;
|
||||
detect-gpio2 = <&tlmm 43 GPIO_ACTIVE_HIGH>;
|
||||
detect-gpio3 = <&tlmm 29 GPIO_ACTIVE_HIGH>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
wsi: wsi {
|
||||
id = <0>;
|
||||
num_chip = <2>;
|
||||
|
||||
@@ -298,6 +298,13 @@
|
||||
};
|
||||
};
|
||||
|
||||
poe {
|
||||
compatible = "poe-judge";
|
||||
detect-mode = <0x11>;
|
||||
detect_gpio = <&tlmm 0x17 0>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x2>;
|
||||
|
||||
|
||||
@@ -298,6 +298,13 @@
|
||||
};
|
||||
};
|
||||
|
||||
poe {
|
||||
compatible = "poe-judge";
|
||||
detect-mode = <0x11>;
|
||||
detect_gpio = <&tlmm 0x17 0>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x2>;
|
||||
|
||||
|
||||
556
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf672.dts
Normal file
556
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-cig-wf672.dts
Normal file
@@ -0,0 +1,556 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||||
/*
|
||||
* IPQ5332 RDP468 board device tree source
|
||||
*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include "ipq5332.dtsi"
|
||||
#include "ipq5332-default-memory.dtsi"
|
||||
|
||||
/ {
|
||||
model = "CIG WF672";
|
||||
compatible = "cig,wf672", "qcom,ipq5332-rdp468", "qcom,ipq5332";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart0;
|
||||
serial1 = &blsp1_uart1;
|
||||
ethernet0 = "/soc/dp1";
|
||||
ethernet1 = "/soc/dp2";
|
||||
led-boot = &led_power_green;
|
||||
led-failsafe = &led_power_red;
|
||||
led-running = &led_power_green;
|
||||
led-upgrade = &led_power_green;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0";
|
||||
};
|
||||
|
||||
soc@0 {
|
||||
mdio:mdio@90000 {
|
||||
pinctrl-0 = <&mdio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
/*gpio51 for manhattan reset*/
|
||||
phy-reset-gpio = <&tlmm 21 GPIO_ACTIVE_LOW>;
|
||||
phyaddr_fixup = <0xC90F018>;
|
||||
uniphyaddr_fixup = <0xC90F014>;
|
||||
mdio_clk_fixup; /* MDIO clock sequence fix up flag */
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <1>;
|
||||
compatible ="ethernet-phy-ieee802.3-c45";
|
||||
fixup;
|
||||
};
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <30>;
|
||||
fixup;
|
||||
};
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x1>;
|
||||
|
||||
ess-switch@3a000000 {
|
||||
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
|
||||
switch_lan_bmp = <0x2>; /* lan port bitmap */
|
||||
switch_wan_bmp = <0x4>; /* wan port bitmap */
|
||||
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0*/
|
||||
switch_mac_mode1 = <0xe>; /* mac mode for uniphy instance1*/
|
||||
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
|
||||
|
||||
qcom,port_phyinfo {
|
||||
port@0 {
|
||||
port_id = <1>;
|
||||
phy_address = <1>;
|
||||
ethernet-phy-ieee802.3-c45;
|
||||
forced-speed = <2500>;
|
||||
forced-duplex = <1>;
|
||||
mdiobus = <&mdio>;
|
||||
};
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
phy_address = <30>;
|
||||
phy_i2c_address =<30>;
|
||||
phy-i2c-mode;
|
||||
sfp_rx_los_pin = <&tlmm 43 0>;
|
||||
sfp_mod_present_pin = <&tlmm 45 0>;
|
||||
sfp_tx_dis_pin = <&extgpio 11 0>;
|
||||
media-type = "sfp"; /* fiber mode */
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
dp2 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <1>;
|
||||
reg = <0x3a500000 0x4000>;
|
||||
qcom,mactype = <1>;
|
||||
local-mac-address = [000000000000];
|
||||
mdio-bus = <&mdio>;
|
||||
qcom,phy-mdio-addr = <1>;
|
||||
qcom,link-poll = <1>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
gmac2:dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <2>;
|
||||
reg = <0x3a504000 0x4000>;
|
||||
qcom,mactype = <1>;
|
||||
local-mac-address = [000000000000];
|
||||
qcom,phy-mdio-addr = <30>;
|
||||
qcom,link-poll = <1>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
x5-cpe {
|
||||
compatible = "x55-poweron";
|
||||
pwykey = <&extgpio2 13 0>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
/* EDMA host driver configuration for the board */
|
||||
edma@3ab00000 {
|
||||
qcom,txdesc-ring-start = <4>; /* Tx desc ring start ID */
|
||||
qcom,txdesc-rings = <12>; /* Total number of Tx desc rings to be provisioned */
|
||||
qcom,mht-txdesc-rings = <8>; /* Extra Tx desc rings to be provisioned for MHT SW ports */
|
||||
qcom,txcmpl-ring-start = <4>; /* Tx complete ring start ID */
|
||||
qcom,txcmpl-rings = <12>; /* Total number of Tx complete rings to be provisioned */
|
||||
qcom,mht-txcmpl-rings = <8>; /* Extra Tx complete rings to be provisioned for mht sw ports. */
|
||||
qcom,rxfill-ring-start = <4>; /* Rx fill ring start ID */
|
||||
qcom,rxfill-rings = <4>; /* Total number of Rx fill rings to be provisioned */
|
||||
qcom,rxdesc-ring-start = <12>; /* Rx desc ring start ID */
|
||||
qcom,rxdesc-rings = <4>; /* Total number of Rx desc rings to be provisioned */
|
||||
qcom,rx-page-mode = <0>; /* Rx fill ring page mode */
|
||||
qcom,tx-map-priority-level = <1>; /* Tx priority level per port */
|
||||
qcom,rx-map-priority-level = <1>; /* Rx priority level per core */
|
||||
qcom,ppeds-num = <2>; /* Number of PPEDS nodes */
|
||||
/* PPE-DS node format: <Rx-fill Tx-cmpl Rx Tx Queue-base Queue-count> */
|
||||
qcom,ppeds-map = <1 1 1 1 32 8>, /* PPEDS Node#0 ring and queue map */
|
||||
<2 2 2 2 40 8>; /* PPEDS Node#1 ring and queue map */
|
||||
qcom,txdesc-map = <8 9 10 11>, /* Port0 per-core Tx ring map */
|
||||
<12 13 14 15>, /* MHT-Port1 per-core Tx ring map */
|
||||
<4 5 6 7>, /* MHT-Port2 per-core Tx ring map/packets from vp*/
|
||||
<16 17 18 19>, /* MHT-Port3 per-core Tx ring map */
|
||||
<20 21 22 23>; /* MHT-Port4 per-core Tx ring map */
|
||||
qcom,txdesc-fc-grp-map = <1 2 3 4 5>; /* Per GMAC flow control group map */
|
||||
qcom,rxfill-map = <4 5 6 7>; /* Per-core Rx fill ring map */
|
||||
qcom,rxdesc-map = <12 13 14 15>; /* Per-core Rx desc ring map */
|
||||
qcom,rx-queue-start = <0>; /* Rx queue start */
|
||||
qcom,rx-ring-queue-map = <0 8 16 24>, /* Priority 0 queues per-core Rx ring map */
|
||||
<1 9 17 25>, /* Priority 1 queues per-core Rx ring map */
|
||||
<2 10 18 26>, /* Priority 2 queues per-core Rx ring map */
|
||||
<3 11 19 27>, /* Priority 3 queues per-core Rx ring map */
|
||||
<4 12 20 28>, /* Priority 4 queues per-core Rx ring map */
|
||||
<5 13 21 29>, /* Priority 5 queues per-core Rx ring map */
|
||||
<6 14 22 30>, /* Priority 6 queues per-core Rx ring map */
|
||||
<7 15 23 31>; /* Priority 7 queues per-core Rx ring map */
|
||||
interrupts = <0 163 4>, /* Tx complete ring id #4 IRQ info */
|
||||
<0 164 4>, /* Tx complete ring id #5 IRQ info */
|
||||
<0 165 4>, /* Tx complete ring id #6 IRQ info */
|
||||
<0 166 4>, /* Tx complete ring id #7 IRQ info */
|
||||
<0 167 4>, /* Tx complete ring id #8 IRQ info */
|
||||
<0 168 4>, /* Tx complete ring id #9 IRQ info */
|
||||
<0 169 4>, /* Tx complete ring id #10 IRQ info */
|
||||
<0 170 4>, /* Tx complete ring id #11 IRQ info */
|
||||
<0 171 4>, /* Tx complete ring id #12 IRQ info */
|
||||
<0 172 4>, /* Tx complete ring id #13 IRQ info */
|
||||
<0 173 4>, /* Tx complete ring id #14 IRQ info */
|
||||
<0 174 4>, /* Tx complete ring id #15 IRQ info */
|
||||
<0 139 4>, /* Rx desc ring id #12 IRQ info */
|
||||
<0 140 4>, /* Rx desc ring id #13 IRQ info */
|
||||
<0 141 4>, /* Rx desc ring id #14 IRQ info */
|
||||
<0 142 4>, /* Rx desc ring id #15 IRQ info */
|
||||
<0 191 4>, /* Misc error IRQ info */
|
||||
<0 160 4>, /* PPEDS Node #1(TxComp ring id #1) TxComplete IRQ info */
|
||||
<0 128 4>, /* PPEDS Node #1(Rx Desc ring id #1) Rx Desc IRQ info */
|
||||
<0 152 4>, /* PPEDS Node #1(RxFill Desc ring id #1) Rx Fill IRQ info */
|
||||
<0 161 4>, /* PPEDS Node #2(TxComp ring id #2) TxComplete IRQ info */
|
||||
<0 129 4>, /* PPEDS Node #2(Rx Desc ring id #2) Rx Desc IRQ info */
|
||||
<0 153 4>, /* PPEDS Node #2(RxFill Desc ring id #2) Rx Fill IRQ info */
|
||||
<0 175 4>, /* MHT port Tx complete ring id #16 IRQ info */
|
||||
<0 176 4>, /* MHT port Tx complete ring id #17 IRQ info */
|
||||
<0 177 4>, /* MHT port Tx complete ring id #18 IRQ info */
|
||||
<0 178 4>, /* MHT port Tx complete ring id #19 IRQ info */
|
||||
<0 179 4>, /* MHT port Tx complete ring id #20 IRQ info */
|
||||
<0 180 4>, /* MHT port Tx complete ring id #21 IRQ info */
|
||||
<0 181 4>, /* MHT port Tx complete ring id #22 IRQ info */
|
||||
<0 182 4>; /* MHT port Tx complete ring id #23 IRQ info */
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
led_power_red:red {
|
||||
label = "pwm:red";
|
||||
pwms = <&pwm 3 1250000>;
|
||||
max-brightness = <160>;
|
||||
linux,default-trigger = "none";
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led_power_green:green {
|
||||
label = "pwm:green";
|
||||
pwms = <&pwm 2 1250000>;
|
||||
max-brightness = <160>;
|
||||
linux,default-trigger = "none";
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led_power_blue: blue {
|
||||
label = "pwm:blue";
|
||||
pwms = <&pwm 1 1250000>;
|
||||
max-brightness = <160>;
|
||||
linux,default-trigger = "none";
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
button@1 {
|
||||
label = "rst";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
poe {
|
||||
compatible = "poe-judge";
|
||||
detect-mode = <0x4>;
|
||||
detect-gpio1 = <&extgpio 0 0>;
|
||||
detect-gpio2 = <&extgpio 1 0>;
|
||||
detect-gpio3 = <&extgpio 2 0>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
wsi: wsi {
|
||||
id = <0>;
|
||||
num_chip = <2>;
|
||||
status = "okay";
|
||||
chip_info = <0 1 1>,
|
||||
<1 1 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
led-gpio = <&tlmm 36 GPIO_ACTIVE_HIGH>;
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,rproc_rpd = <&q6v5_wcss>;
|
||||
qcom,multipd_arch;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
|
||||
memory-region = <&q6_region>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <0>;
|
||||
qcom,board_id = <0x12>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qcn9224_pcie1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_uart0 {
|
||||
pinctrl-0 = <&serial_0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_uart1 {
|
||||
pinctrl-0 = <&serial_1_pins &pta_slic>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_i2c1 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-0 = <&i2c_1_pins>;
|
||||
pinctrl-names = "default";
|
||||
extgpio:pca9555@20{
|
||||
compatible = "nxp,pca9555";
|
||||
reg = <0x20>;
|
||||
pinctrl-names = "default";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "okay";
|
||||
|
||||
};
|
||||
extgpio2:pca9555@21{
|
||||
compatible = "nxp,pca9555";
|
||||
reg = <0x21>;
|
||||
pinctrl-names = "default";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
lsm303_acc@19{
|
||||
compatible = "st,lsm303agr_acc";
|
||||
reg = <0x19>;
|
||||
};
|
||||
lsm303_mag@1e{
|
||||
compatible = "st,lsm303agr_mag";
|
||||
reg = <0x1e>;
|
||||
};
|
||||
ilps22qs@5c{
|
||||
compatible = "st,ilps22qs";
|
||||
reg = <0x5c>;
|
||||
};
|
||||
temp-sense@70 {
|
||||
compatible = "ti,tmp103";
|
||||
reg = <0x70>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_spi0 {
|
||||
pinctrl-0 = <&spi_0_data_clk_pins &spi_0_cs_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "n25q128a11", "micron,n25q128a11", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
spi-max-frequency = <50000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_spi2 {
|
||||
pinctrl-0 = <&spi_2_pins>;
|
||||
pinctrl-names = "default";
|
||||
cs-select = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sdhc {
|
||||
bus-width = <4>;
|
||||
max-frequency = <192000000>;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
non-removable;
|
||||
pinctrl-0 = <&sdc_default_state>;
|
||||
reset = <&tlmm 20 0>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&sleep_clk {
|
||||
clock-frequency = <32000>;
|
||||
};
|
||||
|
||||
&xo {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie1_phy_x2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie0_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
pinctrl-0 = <&pcie0_default_state>;
|
||||
pinctrl-names = "default";
|
||||
perst-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie1 {
|
||||
pinctrl-0 = <&pcie1_default_state>;
|
||||
pinctrl-names = "default";
|
||||
perst-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
pcie1_rp {
|
||||
reg = <0 0 0 0 0>;
|
||||
|
||||
qcom,mhi@1 {
|
||||
reg = <0 0 0 0 0>;
|
||||
boot-args = <0x2 0x4 0x34 0x3 0x0 0x0 /* MX Rail, GPIO52, Drive strength 0x3 */
|
||||
0x4 0x4 0x18 0x3 0x0 0x0 /* RFA1p2 Rail, GPIO24, Drive strength 0x3 */
|
||||
0x0 0x4 0x0 0x0 0x0 0x0>; /* End of arguments */
|
||||
memory-region = <&qcn9224_pcie1>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <1>;
|
||||
qcom,board_id = <0x1015>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* PINCTRL */
|
||||
|
||||
&tlmm {
|
||||
i2c_1_pins: i2c-1-state {
|
||||
pins = "gpio29", "gpio30";
|
||||
function = "blsp1_i2c0";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
spi_2_pins: spi-2-pins {
|
||||
pins = "gpio33", "gpio34", "gpio35", "gpio36";
|
||||
function = "blsp2_spi0";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
pta_slic: pta_slic {
|
||||
pta1_0 {
|
||||
pins = "gpio49";
|
||||
function = "pta1_0";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
pta1_1 {
|
||||
pins = "gpio50";
|
||||
function = "pta1_1";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
pta1_2 {
|
||||
pins = "gpio51";
|
||||
function = "pta1_2";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
spi_0_data_clk_pins: spi-0-data-clk-state {
|
||||
pins = "gpio14", "gpio15", "gpio16";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
spi_0_cs_pins: spi-0-cs-state {
|
||||
pins = "gpio17";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
serial_1_pins: serial1-pinmux {
|
||||
pins = "gpio33", "gpio34", "gpio35", "gpio36";
|
||||
function = "blsp1_uart2";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
button_pins: button-state {
|
||||
pins = "gpio24";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
pwm_pins: pwm-state {
|
||||
|
||||
mux_1 {
|
||||
pins = "gpio25";
|
||||
function = "pwm2";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
mux_2 {
|
||||
pins = "gpio26";
|
||||
function = "pwm2";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
mux_3 {
|
||||
pins = "gpio31";
|
||||
function = "pwm1";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
sdc_default_state: sdc-default-state {
|
||||
clk-pins {
|
||||
pins = "gpio13";
|
||||
function = "sdc_clk";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
cmd-pins {
|
||||
pins = "gpio12";
|
||||
function = "sdc_cmd";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
data-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11";
|
||||
function = "sdc_data";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pcie0_default_state: pcie0-default-state {
|
||||
pins = "gpio38";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
output-low;
|
||||
};
|
||||
|
||||
pcie1_default_state: pcie1-default-state {
|
||||
pins = "gpio47";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
&license_manager {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
qcom,select-utmi-as-pipe-clk;
|
||||
status = "okay";
|
||||
dwc3@8a00000 {
|
||||
/delete-property/ #phy-cells;
|
||||
/delete-property/ phys;
|
||||
/delete-property/ phy-names;
|
||||
};
|
||||
};
|
||||
|
||||
&pwm {
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
pinctrl-names = "default";
|
||||
dft-pwm-status = <0>, <0>, <1>, <0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hs_m31phy_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "ipq5332-default-memory.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Sercomm WiFi-7";
|
||||
model = "Sercomm AP72TIP-v4";
|
||||
compatible = "sercomm,ap72tip-v4", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332";
|
||||
|
||||
aliases {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "ipq5332-default-memory.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Sercomm WiFi-7";
|
||||
model = "Sercomm AP72TIP";
|
||||
compatible = "sercomm,ap72tip", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332";
|
||||
|
||||
aliases {
|
||||
@@ -255,7 +255,7 @@
|
||||
gpios = <&tca6416 14 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
/*
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
@@ -263,11 +263,11 @@
|
||||
button@1 {
|
||||
label = "rst";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
|
||||
gpios = <&tlmm 1 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};*/
|
||||
};
|
||||
|
||||
wsi: wsi {
|
||||
id = <0>;
|
||||
@@ -546,13 +546,13 @@
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};*/
|
||||
/*
|
||||
|
||||
button_pins: button-state {
|
||||
pins = "gpio25";
|
||||
pins = "gpio1";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};*/
|
||||
};
|
||||
|
||||
pwm_pins: pwm-state {
|
||||
pins = "gpio46";
|
||||
|
||||
687
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-sonicfi-rap750e-s.dts
Executable file
687
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-sonicfi-rap750e-s.dts
Executable file
@@ -0,0 +1,687 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||||
/*
|
||||
* IPQ5332 RDP477 board device tree source
|
||||
*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "ipq5332.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include "ipq5332-default-memory.dtsi"
|
||||
|
||||
/ {
|
||||
model = "SONICFI RAP750E-S";
|
||||
compatible = "sonicfi,rap750e-s","qcom,ipq5332-ap-mi01.3-c2", "qcom,ipq5332";
|
||||
|
||||
#ifdef __IPQ_MEM_PROFILE_512_MB__
|
||||
/* 512M Memory Layout for IPQ5332 + QCN6432
|
||||
* +==========+==============+========================+
|
||||
* | | | |
|
||||
* | Region | Start Offset | Size |
|
||||
* | | | |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | Q6 | | |
|
||||
* | code/ | 0x4A900000 | 20MB |
|
||||
* | data | | |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | data | 0x4BD00000 | 17MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | M3 Dump | 0x4CE00000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | QDSS | 0x4CF00000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |IPQ5332 | | |
|
||||
* | CALDB | 0x4D000000 | 3MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | data | 0x4D300000 | 16MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | M3 Dump | 0x4E300000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | QDSS | 0x4E400000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | CALDB | 0x4E500000 | 5MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* |MEM_HOLE | 0x4EA00000 | 5MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | | | |
|
||||
* | MLO | 0x4EF00000 | 17MB |
|
||||
* +==================================================+
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | Rest of memory for Linux |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +==================================================+
|
||||
*/
|
||||
|
||||
reserved-memory {
|
||||
|
||||
/delete-node/ m3_dump@4cc00000;
|
||||
/delete-node/ q6_etr_dump@1;
|
||||
/delete-node/ mlo_global_mem_0@0x4db00000;
|
||||
/delete-node/ wcnss@4a900000;
|
||||
/delete-node/ q6_caldb_region@4ce00000;
|
||||
|
||||
q6_mem_regions: q6_mem_regions@4A900000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4A900000 0x0 0x4600000>;
|
||||
};
|
||||
|
||||
q6_code_data: q6_code_data@4A900000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4A900000 0x0 0x1400000>;
|
||||
};
|
||||
|
||||
q6_ipq5332_data: q6_ipq5332_data@4BD00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4BD00000 0x0 0x1100000>;
|
||||
};
|
||||
|
||||
m3_dump: m3_dump@4CE00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4CE00000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_etr_region: q6_etr_dump@4CF00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4CF00000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_ipq5332_caldb: q6_ipq5332_caldb@4D000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D000000 0x0 0x300000>;
|
||||
};
|
||||
|
||||
q6_qcn6432_data_1: q6_qcn6432_data_1@4D300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D300000 0x0 0x1000000>;
|
||||
};
|
||||
|
||||
m3_dump_qcn6432_1: m3_dump_qcn6432_1@4E300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E300000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6432_etr_1: q6_qcn6432_etr_1@4E400000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E400000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
q6_qcn6432_caldb_1: q6_qcn6432_caldb_1@4E500000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4E500000 0x0 0x500000>;
|
||||
};
|
||||
|
||||
mlo_global_mem0: mlo_global_mem_0@4EF00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4EF00000 0x0 0x1100000>;
|
||||
};
|
||||
};
|
||||
#else
|
||||
/* 1G Memory Layout for IPQ5332 + QCN6432
|
||||
* +==========+==============+========================+
|
||||
* | | | |
|
||||
* | Region | Start Offset | Size |
|
||||
* | | | |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | Q6 | | |
|
||||
* | code/ | 0x4A900000 | 20MB |
|
||||
* | data | | |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | data | 0x4BD00000 | 21MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | M3 Dump | 0x4D200000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | IPQ5332 | | |
|
||||
* | QDSS | 0x4D300000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |IPQ5332 | | |
|
||||
* | CALDB | 0x4D400000 | 5MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | data | 0x4D900000 | 21MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | M3 Dump | 0x4EE00000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | QDSS | 0x4EF00000 | 1MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* | CALDB | 0x4F000000 | 5MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* |QCN6432_1| | |
|
||||
* |MEM_HOLE | 0x4F500000 | 5MB |
|
||||
* +---------+--------------+-------------------------+
|
||||
* | | | |
|
||||
* | MLO | 0x4FA00000 | 17MB |
|
||||
* +==================================================+
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | Rest of memory for Linux |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +==================================================+
|
||||
*/
|
||||
reserved-memory {
|
||||
|
||||
/delete-node/ m3_dump@4cc00000;
|
||||
/delete-node/ q6_etr_dump@1;
|
||||
/delete-node/ mlo_global_mem_0@0x4db00000;
|
||||
/delete-node/ wcnss@4a900000;
|
||||
/delete-node/ q6_caldb_region@4ce00000;
|
||||
|
||||
q6_mem_regions: q6_mem_regions@4A900000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4A900000 0x0 0x5100000>;
|
||||
};
|
||||
q6_code_data: q6_code_data@4A900000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4A900000 0x0 0x1400000>;
|
||||
};
|
||||
q6_ipq5332_data: q6_ipq5332_data@4BD00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4BD00000 0x0 0x1500000>;
|
||||
};
|
||||
m3_dump: m3_dump@4D200000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D200000 0x0 0x100000>;
|
||||
};
|
||||
q6_etr_region: q6_etr_dump@4D300000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D300000 0x0 0x100000>;
|
||||
};
|
||||
q6_ipq5332_caldb: q6_ipq5332_caldb@4D400000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D400000 0x0 0x500000>;
|
||||
};
|
||||
q6_qcn6432_data_1: q6_qcn6432_data_1@4D900000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4D900000 0x0 0x1500000>;
|
||||
};
|
||||
m3_dump_qcn6432_1: m3_dump_qcn6432_1@4EE00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4EE00000 0x0 0x100000>;
|
||||
};
|
||||
q6_qcn6432_etr_1: q6_qcn6432_etr_1@4EF00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4EF00000 0x0 0x100000>;
|
||||
};
|
||||
q6_qcn6432_caldb_1: q6_qcn6432_caldb_1@4F000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4F000000 0x0 0x500000>;
|
||||
};
|
||||
mlo_global_mem0: mlo_global_mem_0@4FA00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4FA00000 0x0 0x1100000>;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
aliases {
|
||||
serial0 = &blsp1_uart0;
|
||||
serial1 = &blsp1_uart1;
|
||||
ethernet0 = "/soc/dp1";
|
||||
//ethernet1 = "/soc/dp2";
|
||||
led-boot = &led_power;
|
||||
led-failsafe = &led_power;
|
||||
led-running = &led_power;
|
||||
led-upgrade = &led_power;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0";
|
||||
};
|
||||
|
||||
soc@0 {
|
||||
mdio:mdio@90000 {
|
||||
pinctrl-0 = <&mdio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
/*gpio26 for manhattan reset*/
|
||||
phy-reset-gpio = <&tlmm 26 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <16>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
button@1 {
|
||||
label = "reset";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
red {
|
||||
label = "pwm:red";
|
||||
pwms = <&pwm 2 1250000>;
|
||||
max-brightness = <255>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
|
||||
green {
|
||||
label = "pwm:green";
|
||||
pwms = <&pwm 3 1250000>;
|
||||
max-brightness = <255>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
|
||||
led_power: blue {
|
||||
label = "pwm:blue";
|
||||
pwms = <&pwm 1 1250000>;
|
||||
max-brightness = <255>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
|
||||
white {
|
||||
label = "pwm:white";
|
||||
pwms = <&pwm 0 1250000>;
|
||||
max-brightness = <255>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x1>;
|
||||
|
||||
ess-switch@3a000000 {
|
||||
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
|
||||
switch_lan_bmp = <0x4>; /* lan port bitmap */
|
||||
switch_wan_bmp = <0x0>; /* wan port bitmap */
|
||||
switch_mac_mode = <0xff>; /* mac mode for uniphy instance0*/
|
||||
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
|
||||
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
|
||||
|
||||
qcom,port_phyinfo {
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
phy_address = <16>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <2>;
|
||||
reg = <0x3a504000 0x4000>;
|
||||
qcom,mactype = <1>;
|
||||
local-mac-address = [000000000000];
|
||||
mdio-bus = <&mdio>;
|
||||
qcom,phy-mdio-addr = <16>;
|
||||
qcom,link-poll = <1>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
/* EDMA host driver configuration for the board */
|
||||
edma@3ab00000 {
|
||||
qcom,txdesc-ring-start = <4>; /* Tx desc ring start ID */
|
||||
qcom,txdesc-rings = <12>; /* Total number of Tx desc rings to be provisioned */
|
||||
qcom,mht-txdesc-rings = <8>; /* Extra Tx desc rings to be provisioned for MHT SW ports */
|
||||
qcom,txcmpl-ring-start = <4>; /* Tx complete ring start ID */
|
||||
qcom,txcmpl-rings = <12>; /* Total number of Tx complete rings to be provisioned */
|
||||
qcom,mht-txcmpl-rings = <8>; /* Extra Tx complete rings to be provisioned for mht sw ports. */
|
||||
qcom,rxfill-ring-start = <4>; /* Rx fill ring start ID */
|
||||
qcom,rxfill-rings = <4>; /* Total number of Rx fill rings to be provisioned */
|
||||
qcom,rxdesc-ring-start = <12>; /* Rx desc ring start ID */
|
||||
qcom,rxdesc-rings = <4>; /* Total number of Rx desc rings to be provisioned */
|
||||
qcom,rx-page-mode = <0>; /* Rx fill ring page mode */
|
||||
qcom,tx-map-priority-level = <1>; /* Tx priority level per port */
|
||||
qcom,rx-map-priority-level = <1>; /* Rx priority level per core */
|
||||
qcom,ppeds-num = <2>; /* Number of PPEDS nodes */
|
||||
/* PPE-DS node format: <Rx-fill Tx-cmpl Rx Tx Queue-base Queue-count> */
|
||||
qcom,ppeds-map = <1 1 1 1 32 8>, /* PPEDS Node#0 ring and queue map */
|
||||
<2 2 2 2 40 8>; /* PPEDS Node#1 ring and queue map */
|
||||
qcom,txdesc-map = <8 9 10 11>, /* Port0 per-core Tx ring map */
|
||||
<12 13 14 15>, /* MHT-Port1 per-core Tx ring map */
|
||||
<4 5 6 7>, /* MHT-Port2 per-core Tx ring map/packets from vp*/
|
||||
<16 17 18 19>, /* MHT-Port3 per-core Tx ring map */
|
||||
<20 21 22 23>; /* MHT-Port4 per-core Tx ring map */
|
||||
qcom,txdesc-fc-grp-map = <1 2 3 4 5>; /* Per GMAC flow control group map */
|
||||
qcom,rxfill-map = <4 5 6 7>; /* Per-core Rx fill ring map */
|
||||
qcom,rxdesc-map = <12 13 14 15>; /* Per-core Rx desc ring map */
|
||||
qcom,rx-queue-start = <0>; /* Rx queue start */
|
||||
qcom,rx-ring-queue-map = <0 8 16 24>, /* Priority 0 queues per-core Rx ring map */
|
||||
<1 9 17 25>, /* Priority 1 queues per-core Rx ring map */
|
||||
<2 10 18 26>, /* Priority 2 queues per-core Rx ring map */
|
||||
<3 11 19 27>, /* Priority 3 queues per-core Rx ring map */
|
||||
<4 12 20 28>, /* Priority 4 queues per-core Rx ring map */
|
||||
<5 13 21 29>, /* Priority 5 queues per-core Rx ring map */
|
||||
<6 14 22 30>, /* Priority 6 queues per-core Rx ring map */
|
||||
<7 15 23 31>; /* Priority 7 queues per-core Rx ring map */
|
||||
interrupts = <0 163 4>, /* Tx complete ring id #4 IRQ info */
|
||||
<0 164 4>, /* Tx complete ring id #5 IRQ info */
|
||||
<0 165 4>, /* Tx complete ring id #6 IRQ info */
|
||||
<0 166 4>, /* Tx complete ring id #7 IRQ info */
|
||||
<0 167 4>, /* Tx complete ring id #8 IRQ info */
|
||||
<0 168 4>, /* Tx complete ring id #9 IRQ info */
|
||||
<0 169 4>, /* Tx complete ring id #10 IRQ info */
|
||||
<0 170 4>, /* Tx complete ring id #11 IRQ info */
|
||||
<0 171 4>, /* Tx complete ring id #12 IRQ info */
|
||||
<0 172 4>, /* Tx complete ring id #13 IRQ info */
|
||||
<0 173 4>, /* Tx complete ring id #14 IRQ info */
|
||||
<0 174 4>, /* Tx complete ring id #15 IRQ info */
|
||||
<0 139 4>, /* Rx desc ring id #12 IRQ info */
|
||||
<0 140 4>, /* Rx desc ring id #13 IRQ info */
|
||||
<0 141 4>, /* Rx desc ring id #14 IRQ info */
|
||||
<0 142 4>, /* Rx desc ring id #15 IRQ info */
|
||||
<0 191 4>, /* Misc error IRQ info */
|
||||
<0 160 4>, /* PPEDS Node #1(TxComp ring id #1) TxComplete IRQ info */
|
||||
<0 128 4>, /* PPEDS Node #1(Rx Desc ring id #1) Rx Desc IRQ info */
|
||||
<0 152 4>, /* PPEDS Node #1(RxFill Desc ring id #1) Rx Fill IRQ info */
|
||||
<0 161 4>, /* PPEDS Node #2(TxComp ring id #2) TxComplete IRQ info */
|
||||
<0 129 4>, /* PPEDS Node #2(Rx Desc ring id #2) Rx Desc IRQ info */
|
||||
<0 153 4>, /* PPEDS Node #2(RxFill Desc ring id #2) Rx Fill IRQ info */
|
||||
<0 175 4>, /* MHT port Tx complete ring id #16 IRQ info */
|
||||
<0 176 4>, /* MHT port Tx complete ring id #17 IRQ info */
|
||||
<0 177 4>, /* MHT port Tx complete ring id #18 IRQ info */
|
||||
<0 178 4>, /* MHT port Tx complete ring id #19 IRQ info */
|
||||
<0 179 4>, /* MHT port Tx complete ring id #20 IRQ info */
|
||||
<0 180 4>, /* MHT port Tx complete ring id #21 IRQ info */
|
||||
<0 181 4>, /* MHT port Tx complete ring id #22 IRQ info */
|
||||
<0 182 4>; /* MHT port Tx complete ring id #23 IRQ info */
|
||||
};
|
||||
|
||||
wsi: wsi {
|
||||
id = <0>;
|
||||
num_chip = <2>;
|
||||
status = "okay";
|
||||
chip_info = <0 1 1>,
|
||||
<1 1 0>;
|
||||
};
|
||||
|
||||
q6v5_wcss: remoteproc@d100000 {
|
||||
boot-args = <0x1 0x4 0x3 0x0 0x26 0x2>;
|
||||
memory-region = <&q6_mem_regions>;
|
||||
|
||||
q6_wcss_pd1: remoteproc_pd1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
q6_wcss_pd2: remoteproc_pd2 {
|
||||
compatible = "qcom,ipq5332-wcss-pcie-mpd";
|
||||
firmware = "IPQ5332/q6_fw2.mdt";
|
||||
m3_firmware = "qcn6432/iu_fw.mdt";
|
||||
interrupts-extended = <&wcss_smp2p_in 16 0>,
|
||||
<&wcss_smp2p_in 17 0>,
|
||||
<&wcss_smp2p_in 20 0>,
|
||||
<&wcss_smp2p_in 19 0>;
|
||||
interrupt-names = "fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
qcom,smem-states = <&wcss_smp2p_out 16>,
|
||||
<&wcss_smp2p_out 17>,
|
||||
<&wcss_smp2p_out 18>;
|
||||
qcom,smem-state-names = "shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart0 {
|
||||
pinctrl-0 = <&serial_0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
/*
|
||||
&blsp1_uart1 {
|
||||
pinctrl-0 = <&serial_1_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
};
|
||||
*/
|
||||
&blsp1_i2c1 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-0 = <&i2c_1_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_spi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sdhc {
|
||||
bus-width = <4>;
|
||||
max-frequency = <192000000>;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
non-removable;
|
||||
pinctrl-0 = <&sdc_default_state>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sleep_clk {
|
||||
clock-frequency = <32000>;
|
||||
};
|
||||
|
||||
&xo {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qpic_nand {
|
||||
pinctrl-0 = <&qspi_default_state>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
nandcs@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
nand-ecc-strength = <8>;
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-bus-width = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
/* PINCTRL */
|
||||
|
||||
&tlmm {
|
||||
qspi_default_state: qspi-default-state {
|
||||
qspi_clock {
|
||||
pins = "gpio13";
|
||||
function = "qspi_clk";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
qspi_cs {
|
||||
pins = "gpio12";
|
||||
function = "qspi_cs";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
qspi_data {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11";
|
||||
function = "qspi_data";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
pwm_pins: pwm_pinmux {
|
||||
/* PWM LED GREEN */
|
||||
mux_1 {
|
||||
pins = "gpio43";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
/* PWM LED BLUE */
|
||||
mux_2 {
|
||||
pins = "gpio45";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
/* PWM LED RED */
|
||||
mux_3 {
|
||||
pins = "gpio44";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
/* PWM LED WHITE */
|
||||
mux_4 {
|
||||
pins = "gpio46";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
};
|
||||
/*
|
||||
serial_1_pins: serial1-pinmux {
|
||||
pins = "gpio33", "gpio34", "gpio35", "gpio36";
|
||||
function = "blsp1_uart2";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
*/
|
||||
i2c_1_pins: i2c-1-state {
|
||||
pins = "gpio29", "gpio30";
|
||||
function = "blsp1_i2c0";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
/*
|
||||
gpio_leds_default: gpio-leds-default-state {
|
||||
pins = "gpio36";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
*/
|
||||
button_pins: button-state {
|
||||
pins = "gpio24";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
sdc_default_state: sdc-default-state {
|
||||
clk-pins {
|
||||
pins = "gpio13";
|
||||
function = "sdc_clk";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
cmd-pins {
|
||||
pins = "gpio12";
|
||||
function = "sdc_cmd";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
data-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11";
|
||||
function = "sdc_data";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&license_manager {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
qcom,select-utmi-as-pipe-clk;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pwm {
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
used-pwm-indices = <1>, <1>, <1>, <1>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hs_m31phy_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
qcom,multipd_arch;
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,rproc_rpd = <&q6v5_wcss>;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
|
||||
qcom,bdf-addr = <0x4BD00000 0x4BD00000 0x0 0x0 0x0 0x0>;
|
||||
qcom,caldb-addr = <0x4D400000 0x4D000000 0x0 0x0 0x0 0x0>;
|
||||
#ifdef __IPQ_MEM_PROFILE_512_MB__
|
||||
qcom,tgt-mem-mode = <1>;
|
||||
qcom,caldb-size = <0x300000>;
|
||||
#else
|
||||
qcom,tgt-mem-mode = <0>;
|
||||
qcom,caldb-size = <0x500000>;
|
||||
#endif
|
||||
qcom,board_id = <0x1b>;
|
||||
memory-region = <&q6_ipq5332_data>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
qcom,multipd_arch;
|
||||
qcom,rproc = <&q6_wcss_pd2>;
|
||||
qcom,rproc_rpd = <&q6v5_wcss>;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
|
||||
qcom,bdf-addr = <0x4D900000 0x4D300000 0x0 0x0 0x0 0x0>;
|
||||
qcom,caldb-addr = <0x4F000000 0x4E500000 0x0 0x0 0x0 0x0>;
|
||||
qcom,umac-irq-reset-addr = <0x20000884>;
|
||||
qcom,caldb-size = <0x500000>;
|
||||
#ifdef __IPQ_MEM_PROFILE_512_MB__
|
||||
qcom,tgt-mem-mode = <1>;
|
||||
#else
|
||||
qcom,tgt-mem-mode = <0>;
|
||||
#endif
|
||||
qcom,board_id = <0x060>;
|
||||
memory-region = <&q6_qcn6432_data_1>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <1>;
|
||||
status = "okay";
|
||||
interrupts = <GIC_SPI 33 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "umac_reset";
|
||||
};
|
||||
592
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-zyxel-nwa130be.dts
Executable file
592
feeds/qca-wifi-7/ipq53xx/dts/ipq5332-zyxel-nwa130be.dts
Executable file
@@ -0,0 +1,592 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||||
/*
|
||||
* IPQ5332 RDP468 board device tree source
|
||||
*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include "ipq5332.dtsi"
|
||||
#include "ipq5332-default-memory.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Zyxel NWA130BE";
|
||||
compatible = "zyxel,nwa130be", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332-rdp468", "qcom,ipq5332";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart0;
|
||||
serial1 = &blsp1_uart1;
|
||||
ethernet0 = "/soc/dp1";
|
||||
ethernet1 = "/soc/dp2";
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0";
|
||||
};
|
||||
|
||||
soc@0 {
|
||||
mdio:mdio@90000 {
|
||||
pinctrl-0 = <&mdio1_pins &mdio0_pins>;
|
||||
pinctrl-names = "default";
|
||||
/*gpio51 for manhattan reset*/
|
||||
phy-reset-gpio = <&tlmm 51 GPIO_ACTIVE_LOW>;
|
||||
phyaddr_fixup = <0xC90F018>;
|
||||
uniphyaddr_fixup = <0xC90F014>;
|
||||
mdio_clk_fixup; /* MDIO clock sequence fix up flag */
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <1>;
|
||||
fixup;
|
||||
};
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <2>;
|
||||
fixup;
|
||||
};
|
||||
phy2: ethernet-phy@2 {
|
||||
reg = <3>;
|
||||
fixup;
|
||||
};
|
||||
phy3: ethernet-phy@3 {
|
||||
reg = <4>;
|
||||
fixup;
|
||||
};
|
||||
|
||||
switch0@10 {
|
||||
compatible = "qca,qca8386";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x10>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac2>;
|
||||
dsa-tag-protocol = "qca_4b";
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan1";
|
||||
phy-handle = <&phy0>;
|
||||
phy-mode = "usxgmii";
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
phy-handle = <&phy1>;
|
||||
phy-mode = "usxgmii";
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
phy-handle = <&phy2>;
|
||||
phy-mode = "usxgmii";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ess-instance {
|
||||
num_devices = <0x2>;
|
||||
|
||||
ess-switch@3a000000 {
|
||||
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
|
||||
switch_lan_bmp = <0x2>; /* lan port bitmap */
|
||||
switch_wan_bmp = <0x4>; /* wan port bitmap */
|
||||
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0*/
|
||||
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
|
||||
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
|
||||
|
||||
qcom,port_phyinfo {
|
||||
port@0 {
|
||||
port_id = <1>;
|
||||
forced-speed = <2500>;
|
||||
forced-duplex = <1>;
|
||||
};
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
phy_address = <4>;
|
||||
};
|
||||
};
|
||||
|
||||
led_source@5 {
|
||||
source = <5>;
|
||||
mode = "normal";
|
||||
speed = "all";
|
||||
blink_en = "enable";
|
||||
active = "high";
|
||||
};
|
||||
};
|
||||
|
||||
ess-switch1@1 {
|
||||
compatible = "qcom,ess-switch-qca8386";
|
||||
device_id = <1>;
|
||||
switch_access_mode = "mdio";
|
||||
mdio-bus = <&mdio>;
|
||||
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0 */
|
||||
switch_mac_mode1 = <0xff>; /* mac mode1 for uniphy instance1 */
|
||||
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
|
||||
switch_lan_bmp = <0xe>; /* lan port bitmap */
|
||||
switch_wan_bmp = <0x0>; /* wan port bitmap */
|
||||
link-polling-required = <0>;
|
||||
fdb_sync = "interrupt";
|
||||
link-intr-gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
qcom,port_phyinfo {
|
||||
port@0 {
|
||||
port_id = <0>;
|
||||
forced-speed = <2500>;
|
||||
forced-duplex = <1>;
|
||||
};
|
||||
port@1 {
|
||||
port_id = <1>;
|
||||
phy_address = <1>;
|
||||
};
|
||||
port@2 {
|
||||
port_id = <2>;
|
||||
phy_address = <2>;
|
||||
};
|
||||
port@3 {
|
||||
port_id = <3>;
|
||||
phy_address = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
led_source@2 {
|
||||
source = <2>;
|
||||
mode = "normal";
|
||||
speed = "all";
|
||||
blink_en = "enable";
|
||||
active = "high";
|
||||
};
|
||||
led_source@5 {
|
||||
source = <5>;
|
||||
mode = "normal";
|
||||
speed = "all";
|
||||
blink_en = "enable";
|
||||
active = "high";
|
||||
};
|
||||
led_source@8 {
|
||||
source = <8>;
|
||||
mode = "normal";
|
||||
speed = "all";
|
||||
blink_en = "enable";
|
||||
active = "high";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <2>;
|
||||
reg = <0x3a504000 0x4000>;
|
||||
qcom,mactype = <1>;
|
||||
local-mac-address = [000000000000];
|
||||
mdio-bus = <&mdio>;
|
||||
qcom,phy-mdio-addr = <4>;
|
||||
qcom,link-poll = <1>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
gmac2:dp2 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <1>;
|
||||
reg = <0x3a500000 0x4000>;
|
||||
qcom,mactype = <1>;
|
||||
local-mac-address = [000000000000];
|
||||
phy-mode = "sgmii";
|
||||
qcom,mht-dev = <1>;
|
||||
qcom,is_switch_connected = <1>;
|
||||
qcom,ppe-offload-disabled = <1>;
|
||||
};
|
||||
|
||||
/* EDMA host driver configuration for the board */
|
||||
edma@3ab00000 {
|
||||
qcom,txdesc-ring-start = <4>; /* Tx desc ring start ID */
|
||||
qcom,txdesc-rings = <12>; /* Total number of Tx desc rings to be provisioned */
|
||||
qcom,mht-txdesc-rings = <8>; /* Extra Tx desc rings to be provisioned for MHT SW ports */
|
||||
qcom,txcmpl-ring-start = <4>; /* Tx complete ring start ID */
|
||||
qcom,txcmpl-rings = <12>; /* Total number of Tx complete rings to be provisioned */
|
||||
qcom,mht-txcmpl-rings = <8>; /* Extra Tx complete rings to be provisioned for mht sw ports. */
|
||||
qcom,rxfill-ring-start = <4>; /* Rx fill ring start ID */
|
||||
qcom,rxfill-rings = <4>; /* Total number of Rx fill rings to be provisioned */
|
||||
qcom,rxdesc-ring-start = <12>; /* Rx desc ring start ID */
|
||||
qcom,rxdesc-rings = <4>; /* Total number of Rx desc rings to be provisioned */
|
||||
qcom,rx-page-mode = <0>; /* Rx fill ring page mode */
|
||||
qcom,tx-map-priority-level = <1>; /* Tx priority level per port */
|
||||
qcom,rx-map-priority-level = <1>; /* Rx priority level per core */
|
||||
qcom,ppeds-num = <2>; /* Number of PPEDS nodes */
|
||||
/* PPE-DS node format: <Rx-fill Tx-cmpl Rx Tx Queue-base Queue-count> */
|
||||
qcom,ppeds-map = <1 1 1 1 32 8>, /* PPEDS Node#0 ring and queue map */
|
||||
<2 2 2 2 40 8>; /* PPEDS Node#1 ring and queue map */
|
||||
qcom,txdesc-map = <8 9 10 11>, /* Port0 per-core Tx ring map */
|
||||
<12 13 14 15>, /* MHT-Port1 per-core Tx ring map */
|
||||
<4 5 6 7>, /* MHT-Port2 per-core Tx ring map/packets from vp*/
|
||||
<16 17 18 19>, /* MHT-Port3 per-core Tx ring map */
|
||||
<20 21 22 23>; /* MHT-Port4 per-core Tx ring map */
|
||||
qcom,txdesc-fc-grp-map = <1 2 3 4 5>; /* Per GMAC flow control group map */
|
||||
qcom,rxfill-map = <4 5 6 7>; /* Per-core Rx fill ring map */
|
||||
qcom,rxdesc-map = <12 13 14 15>; /* Per-core Rx desc ring map */
|
||||
qcom,rx-queue-start = <0>; /* Rx queue start */
|
||||
qcom,rx-ring-queue-map = <0 8 16 24>, /* Priority 0 queues per-core Rx ring map */
|
||||
<1 9 17 25>, /* Priority 1 queues per-core Rx ring map */
|
||||
<2 10 18 26>, /* Priority 2 queues per-core Rx ring map */
|
||||
<3 11 19 27>, /* Priority 3 queues per-core Rx ring map */
|
||||
<4 12 20 28>, /* Priority 4 queues per-core Rx ring map */
|
||||
<5 13 21 29>, /* Priority 5 queues per-core Rx ring map */
|
||||
<6 14 22 30>, /* Priority 6 queues per-core Rx ring map */
|
||||
<7 15 23 31>; /* Priority 7 queues per-core Rx ring map */
|
||||
interrupts = <0 163 4>, /* Tx complete ring id #4 IRQ info */
|
||||
<0 164 4>, /* Tx complete ring id #5 IRQ info */
|
||||
<0 165 4>, /* Tx complete ring id #6 IRQ info */
|
||||
<0 166 4>, /* Tx complete ring id #7 IRQ info */
|
||||
<0 167 4>, /* Tx complete ring id #8 IRQ info */
|
||||
<0 168 4>, /* Tx complete ring id #9 IRQ info */
|
||||
<0 169 4>, /* Tx complete ring id #10 IRQ info */
|
||||
<0 170 4>, /* Tx complete ring id #11 IRQ info */
|
||||
<0 171 4>, /* Tx complete ring id #12 IRQ info */
|
||||
<0 172 4>, /* Tx complete ring id #13 IRQ info */
|
||||
<0 173 4>, /* Tx complete ring id #14 IRQ info */
|
||||
<0 174 4>, /* Tx complete ring id #15 IRQ info */
|
||||
<0 139 4>, /* Rx desc ring id #12 IRQ info */
|
||||
<0 140 4>, /* Rx desc ring id #13 IRQ info */
|
||||
<0 141 4>, /* Rx desc ring id #14 IRQ info */
|
||||
<0 142 4>, /* Rx desc ring id #15 IRQ info */
|
||||
<0 191 4>, /* Misc error IRQ info */
|
||||
<0 160 4>, /* PPEDS Node #1(TxComp ring id #1) TxComplete IRQ info */
|
||||
<0 128 4>, /* PPEDS Node #1(Rx Desc ring id #1) Rx Desc IRQ info */
|
||||
<0 152 4>, /* PPEDS Node #1(RxFill Desc ring id #1) Rx Fill IRQ info */
|
||||
<0 161 4>, /* PPEDS Node #2(TxComp ring id #2) TxComplete IRQ info */
|
||||
<0 129 4>, /* PPEDS Node #2(Rx Desc ring id #2) Rx Desc IRQ info */
|
||||
<0 153 4>, /* PPEDS Node #2(RxFill Desc ring id #2) Rx Fill IRQ info */
|
||||
<0 175 4>, /* MHT port Tx complete ring id #16 IRQ info */
|
||||
<0 176 4>, /* MHT port Tx complete ring id #17 IRQ info */
|
||||
<0 177 4>, /* MHT port Tx complete ring id #18 IRQ info */
|
||||
<0 178 4>, /* MHT port Tx complete ring id #19 IRQ info */
|
||||
<0 179 4>, /* MHT port Tx complete ring id #20 IRQ info */
|
||||
<0 180 4>, /* MHT port Tx complete ring id #21 IRQ info */
|
||||
<0 181 4>, /* MHT port Tx complete ring id #22 IRQ info */
|
||||
<0 182 4>; /* MHT port Tx complete ring id #23 IRQ info */
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
pinctrl-0 = <&led_pins>;
|
||||
pinctrl-names = "default";
|
||||
led_blue{
|
||||
label = "led_blue";
|
||||
gpio = <&tlmm 22 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "led_blue";
|
||||
default-state = "off";
|
||||
};
|
||||
led_green {
|
||||
label = "led_green";
|
||||
gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "led_green";
|
||||
default-state = "on";
|
||||
};
|
||||
led_white {
|
||||
label = "led_white";
|
||||
gpio = <&tlmm 32 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "led_white";
|
||||
default-state = "off";
|
||||
};
|
||||
led_red {
|
||||
label = "led_red";
|
||||
gpio = <&tlmm 44 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "led_red";
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
button@1 {
|
||||
label = "reset";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
wsi: wsi {
|
||||
id = <0>;
|
||||
num_chip = <2>;
|
||||
status = "okay";
|
||||
chip_info = <0 1 1>,
|
||||
<1 1 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
led-gpio = <&tlmm 36 GPIO_ACTIVE_HIGH>;
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,rproc_rpd = <&q6v5_wcss>;
|
||||
qcom,multipd_arch;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
|
||||
memory-region = <&q6_region>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <0>;
|
||||
qcom,board_id = <0x12>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qcn9224_pcie1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_uart0 {
|
||||
pinctrl-0 = <&serial_0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_uart1 {
|
||||
pinctrl-0 = <&serial_1_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&blsp1_spi0 {
|
||||
pinctrl-0 = <&spi_0_data_clk_pins &spi_0_cs_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "n25q128a11", "micron,n25q128a11", "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
spi-max-frequency = <50000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc {
|
||||
bus-width = <4>;
|
||||
max-frequency = <192000000>;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
non-removable;
|
||||
pinctrl-0 = <&sdc_default_state>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sleep_clk {
|
||||
clock-frequency = <32000>;
|
||||
};
|
||||
|
||||
&xo {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qpic_nand {
|
||||
pinctrl-0 = <&qspi_default_state>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
nandcs@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
nand-ecc-strength = <8>;
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-bus-width = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
&pcie1_phy_x2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie1 {
|
||||
pinctrl-0 = <&pcie1_default_state>;
|
||||
pinctrl-names = "default";
|
||||
perst-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
pcie1_rp {
|
||||
reg = <0 0 0 0 0>;
|
||||
|
||||
qcom,mhi@1 {
|
||||
reg = <0 0 0 0 0>;
|
||||
boot-args = <0x2 0x4 0x34 0x3 0x0 0x0 /* MX Rail, GPIO52, Drive strength 0x3 */
|
||||
0x4 0x4 0x18 0x3 0x0 0x0 /* RFA1p2 Rail, GPIO24, Drive strength 0x3 */
|
||||
0x0 0x4 0x0 0x0 0x0 0x0>; /* End of arguments */
|
||||
memory-region = <&qcn9224_pcie1>;
|
||||
qcom,wsi = <&wsi>;
|
||||
qcom,wsi_index = <1>;
|
||||
qcom,board_id = <0x1019>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* PINCTRL */
|
||||
|
||||
&tlmm {
|
||||
|
||||
led_pins: led_pins {
|
||||
led_blue {
|
||||
pins = "gpio22";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
led_green {
|
||||
pins = "gpio31";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
led_white {
|
||||
pins = "gpio32";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
led_red {
|
||||
pins = "gpio44";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
sdc_default_state: sdc-default-state {
|
||||
clk-pins {
|
||||
pins = "gpio13";
|
||||
function = "sdc_clk";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
cmd-pins {
|
||||
pins = "gpio12";
|
||||
function = "sdc_cmd";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
data-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11";
|
||||
function = "sdc_data";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
spi_0_data_clk_pins: spi-0-data-clk-state {
|
||||
pins = "gpio14", "gpio15", "gpio16";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
spi_0_cs_pins: spi-0-cs-state {
|
||||
pins = "gpio17";
|
||||
function = "blsp0_spi";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
qspi_default_state: qspi-default-state {
|
||||
qspi_clock {
|
||||
pins = "gpio13";
|
||||
function = "qspi_clk";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
qspi_cs {
|
||||
pins = "gpio12";
|
||||
function = "qspi_cs";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
qspi_data {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11";
|
||||
function = "qspi_data";
|
||||
drive-strength = <8>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
serial_1_pins: serial1-pinmux {
|
||||
pins = "gpio33", "gpio34", "gpio35", "gpio36";
|
||||
function = "blsp1_uart2";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
button_pins: button-state {
|
||||
pins = "gpio30";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
pwm_pins: pwm-state {
|
||||
pins = "gpio46";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
pcie1_default_state: pcie1-default-state {
|
||||
pins = "gpio47";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
&license_manager {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
qcom,multiplexed-phy;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm {
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hs_m31phy_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssuniphy_0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -0,0 +1,157 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* STMicroelectronics ilps22qs driver
|
||||
*
|
||||
* Copyright 2023 STMicroelectronics Inc.
|
||||
*
|
||||
* MEMS Software Solutions Team
|
||||
*/
|
||||
|
||||
#ifndef __ST_ILPS22QS_H
|
||||
#define __ST_ILPS22QS_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define ST_ILPS22QS_DEV_NAME "ilps22qs"
|
||||
#define ST_ILPS28QSW_DEV_NAME "ilps28qsw"
|
||||
|
||||
#define ST_ILPS22QS_WHO_AM_I_ADDR 0x0f
|
||||
#define ST_ILPS22QS_WHOAMI_VAL 0xb4
|
||||
|
||||
#define ST_ILPS22QS_CTRL1_ADDR 0x10
|
||||
#define ST_ILPS22QS_ODR_MASK GENMASK(6, 3)
|
||||
|
||||
#define ST_ILPS22QS_CTRL2_ADDR 0x11
|
||||
#define ST_ILPS22QS_SOFT_RESET_MASK BIT(2)
|
||||
#define ST_ILPS22QS_BDU_MASK BIT(3)
|
||||
|
||||
#define ST_ILPS22QS_CTRL3_ADDR 0x12
|
||||
#define ST_ILPS22QS_AH_QVAR_EN_MASK BIT(7)
|
||||
#define ST_ILPS22QS_AH_QVAR_P_AUTO_EN_MASK BIT(5)
|
||||
|
||||
#define ST_ILPS22QS_PRESS_OUT_XL_ADDR 0x28
|
||||
#define ST_ILPS22QS_TEMP_OUT_L_ADDR 0x2b
|
||||
|
||||
#define ST_ILPS22QS_PRESS_FS_AVL_GAIN (1000000000UL / 4096UL)
|
||||
#define ST_ILPS22QS_TEMP_FS_AVL_GAIN 100
|
||||
#define ST_ILPS22QS_QVAR_FS_AVL_GAIN 438000
|
||||
|
||||
#define ST_ILPS22QS_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask))
|
||||
|
||||
#define ST_ILPS22QS_ODR_LIST_NUM 8
|
||||
|
||||
enum st_ilps22qs_sensor_id {
|
||||
ST_ILPS22QS_PRESS = 0,
|
||||
ST_ILPS22QS_TEMP,
|
||||
ST_ILPS22QS_QVAR,
|
||||
ST_ILPS22QS_SENSORS_NUM,
|
||||
};
|
||||
|
||||
struct st_ilps22qs_odr_t {
|
||||
u8 hz;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
struct st_ilps22qs_reg {
|
||||
u8 addr;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
struct st_ilps22qs_odr_table_t {
|
||||
u8 size;
|
||||
struct st_ilps22qs_reg reg;
|
||||
struct st_ilps22qs_odr_t odr_avl[ST_ILPS22QS_ODR_LIST_NUM];
|
||||
};
|
||||
|
||||
struct st_ilps22qs_hw {
|
||||
struct iio_dev *iio_devs[ST_ILPS22QS_SENSORS_NUM];
|
||||
struct workqueue_struct *workqueue;
|
||||
struct regulator *vddio_supply;
|
||||
struct regulator *vdd_supply;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
struct mutex lock;
|
||||
bool interleave;
|
||||
u8 enable_mask;
|
||||
u8 odr;
|
||||
};
|
||||
|
||||
struct st_ilps22qs_sensor {
|
||||
enum st_ilps22qs_sensor_id id;
|
||||
struct work_struct iio_work;
|
||||
struct st_ilps22qs_hw *hw;
|
||||
struct hrtimer hr_timer;
|
||||
ktime_t ktime;
|
||||
int64_t timestamp;
|
||||
char name[32];
|
||||
u32 gain;
|
||||
u8 odr;
|
||||
};
|
||||
|
||||
extern const struct dev_pm_ops st_ilps22qs_pm_ops;
|
||||
|
||||
static inline int st_ilps22qs_update_locked(struct st_ilps22qs_hw *hw,
|
||||
unsigned int addr,
|
||||
unsigned int mask,
|
||||
unsigned int data)
|
||||
{
|
||||
unsigned int val = ST_ILPS22QS_SHIFT_VAL(data, mask);
|
||||
int err;
|
||||
|
||||
mutex_lock(&hw->lock);
|
||||
err = regmap_update_bits(hw->regmap, addr, mask, val);
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int st_ilps22qs_read_locked(struct st_ilps22qs_hw *hw,
|
||||
unsigned int addr, void *val,
|
||||
unsigned int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&hw->lock);
|
||||
err = regmap_bulk_read(hw->regmap, addr, val, len);
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void st_ilps22qs_flush_works(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
flush_workqueue(hw->workqueue);
|
||||
}
|
||||
|
||||
static inline int st_ilps22qs_destroy_workqueue(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
if (hw->workqueue)
|
||||
destroy_workqueue(hw->workqueue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int st_ilps22qs_allocate_workqueue(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
if (!hw->workqueue)
|
||||
hw->workqueue = create_workqueue(ST_ILPS22QS_DEV_NAME);
|
||||
|
||||
return !hw->workqueue ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
static inline s64 st_ilps22qs_get_time_ns(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
return iio_get_time_ns(hw->iio_devs[ST_ILPS22QS_PRESS]);
|
||||
}
|
||||
|
||||
int st_ilps22qs_probe(struct device *dev, struct regmap *regmap);
|
||||
int st_ilps22qs_remove(struct device *dev);
|
||||
|
||||
#endif /* __ST_ILPS22QS_H */
|
||||
@@ -0,0 +1,927 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics ilps22qs driver
|
||||
*
|
||||
* Copyright 2023 STMicroelectronics Inc.
|
||||
*
|
||||
* MEMS Software Solutions Team
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/events.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/kfifo_buf.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include <linux/iio/trigger_consumer.h>
|
||||
#include <linux/iio/triggered_buffer.h>
|
||||
#include <linux/iio/trigger.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if KERNEL_VERSION(6, 11, 0) < LINUX_VERSION_CODE
|
||||
#include <linux/unaligned.h>
|
||||
#else /* LINUX_VERSION_CODE */
|
||||
#include <asm/unaligned.h>
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
|
||||
#include "st_ilps22qs.h"
|
||||
|
||||
static const struct st_ilps22qs_odr_table_t st_ilps22qs_odr_table = {
|
||||
.size = ST_ILPS22QS_ODR_LIST_NUM,
|
||||
.reg = {
|
||||
.addr = ST_ILPS22QS_CTRL1_ADDR,
|
||||
.mask = ST_ILPS22QS_ODR_MASK,
|
||||
},
|
||||
.odr_avl[0] = { 1, 0x01 },
|
||||
.odr_avl[1] = { 4, 0x02 },
|
||||
.odr_avl[2] = { 10, 0x03 },
|
||||
.odr_avl[3] = { 25, 0x04 },
|
||||
.odr_avl[4] = { 50, 0x05 },
|
||||
.odr_avl[5] = { 75, 0x06 },
|
||||
.odr_avl[6] = { 100, 0x07 },
|
||||
.odr_avl[7] = { 200, 0x08 },
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_ilps22qs_press_channels[] = {
|
||||
{
|
||||
.type = IIO_PRESSURE,
|
||||
.address = ST_ILPS22QS_PRESS_OUT_XL_ADDR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
.channel2 = IIO_NO_MOD,
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 'u',
|
||||
.realbits = 24,
|
||||
.storagebits = 32,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_ilps22qs_temp_channels[] = {
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.address = ST_ILPS22QS_TEMP_OUT_L_ADDR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
.channel2 = IIO_NO_MOD,
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 's',
|
||||
.realbits = 16,
|
||||
.storagebits = 16,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_ilps22qs_qvar_channels[] = {
|
||||
{
|
||||
.type = IIO_ALTVOLTAGE,
|
||||
.address = ST_ILPS22QS_PRESS_OUT_XL_ADDR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
.channel2 = IIO_NO_MOD,
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 's',
|
||||
.realbits = 24,
|
||||
.storagebits = 32,
|
||||
.endianness = IIO_LE,
|
||||
}
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1),
|
||||
};
|
||||
|
||||
static enum hrtimer_restart
|
||||
st_ilps22qs_poll_function_read(struct hrtimer *timer)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
|
||||
sensor = container_of((struct hrtimer *)timer,
|
||||
struct st_ilps22qs_sensor, hr_timer);
|
||||
|
||||
sensor->timestamp = st_ilps22qs_get_time_ns(sensor->hw);
|
||||
queue_work(sensor->hw->workqueue, &sensor->iio_work);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static void st_ilps22qs_report_temp(struct st_ilps22qs_sensor *sensor,
|
||||
u8 *tmp, int64_t timestamp)
|
||||
{
|
||||
struct iio_dev *iio_dev = sensor->hw->iio_devs[sensor->id];
|
||||
u8 iio_buf[ALIGN(2, sizeof(s64)) + sizeof(s64)];
|
||||
|
||||
memcpy(iio_buf, tmp, 2);
|
||||
iio_push_to_buffers_with_timestamp(iio_dev, iio_buf, timestamp);
|
||||
}
|
||||
|
||||
static void st_silps22qs_report_press_qvar(struct st_ilps22qs_sensor *sensor,
|
||||
u8 *tmp, int64_t timestamp)
|
||||
{
|
||||
u8 iio_buf[ALIGN(3, sizeof(s64)) + sizeof(s64)];
|
||||
struct st_ilps22qs_hw *hw = sensor->hw;
|
||||
struct iio_dev *iio_dev;
|
||||
|
||||
mutex_lock(&hw->lock);
|
||||
if (hw->interleave) {
|
||||
if (tmp[0] & 0x01)
|
||||
iio_dev = sensor->hw->iio_devs[ST_ILPS22QS_QVAR];
|
||||
else
|
||||
iio_dev = sensor->hw->iio_devs[ST_ILPS22QS_PRESS];
|
||||
} else {
|
||||
iio_dev = sensor->hw->iio_devs[sensor->id];
|
||||
}
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
memcpy(iio_buf, tmp, 3);
|
||||
iio_push_to_buffers_with_timestamp(iio_dev, iio_buf, timestamp);
|
||||
}
|
||||
|
||||
static void st_ilps22qs_poll_function_work(struct work_struct *iio_work)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
struct st_ilps22qs_hw *hw;
|
||||
ktime_t tmpkt, ktdelta;
|
||||
int len;
|
||||
int err;
|
||||
int id;
|
||||
|
||||
sensor = container_of((struct work_struct *)iio_work,
|
||||
struct st_ilps22qs_sensor, iio_work);
|
||||
hw = sensor->hw;
|
||||
id = sensor->id;
|
||||
|
||||
/* adjust delta time */
|
||||
ktdelta = ktime_set(0,
|
||||
(st_ilps22qs_get_time_ns(hw) - sensor->timestamp));
|
||||
|
||||
/* avoid negative value in case of high odr */
|
||||
mutex_lock(&hw->lock);
|
||||
if (ktime_after(sensor->ktime, ktdelta))
|
||||
tmpkt = ktime_sub(sensor->ktime, ktdelta);
|
||||
else
|
||||
tmpkt = sensor->ktime;
|
||||
|
||||
hrtimer_start(&sensor->hr_timer, tmpkt, HRTIMER_MODE_REL);
|
||||
mutex_unlock(&sensor->hw->lock);
|
||||
|
||||
len = hw->iio_devs[id]->channels->scan_type.realbits >> 3;
|
||||
|
||||
switch (id) {
|
||||
case ST_ILPS22QS_PRESS:
|
||||
case ST_ILPS22QS_QVAR: {
|
||||
u8 data[3];
|
||||
|
||||
err = st_ilps22qs_read_locked(hw,
|
||||
hw->iio_devs[id]->channels->address,
|
||||
data, len);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
st_silps22qs_report_press_qvar(sensor, data, sensor->timestamp);
|
||||
}
|
||||
break;
|
||||
case ST_ILPS22QS_TEMP: {
|
||||
u8 data[2];
|
||||
|
||||
err = st_ilps22qs_read_locked(hw,
|
||||
hw->iio_devs[id]->channels->address,
|
||||
data, len);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
st_ilps22qs_report_temp(sensor, data, sensor->timestamp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int st_ilps22qs_check_whoami(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
int data;
|
||||
int err;
|
||||
|
||||
err = regmap_read(hw->regmap, ST_ILPS22QS_WHO_AM_I_ADDR, &data);
|
||||
if (err < 0) {
|
||||
dev_err(hw->dev, "failed to read whoami register\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data != ST_ILPS22QS_WHOAMI_VAL) {
|
||||
dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __maybe_unused int st_ilps22qs_reg_access(struct iio_dev *iio_dev,
|
||||
unsigned int reg,
|
||||
unsigned int writeval,
|
||||
unsigned int *readval)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor = iio_priv(iio_dev);
|
||||
int ret;
|
||||
|
||||
ret = iio_device_claim_direct_mode(iio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (readval == NULL)
|
||||
ret = regmap_write(sensor->hw->regmap, reg, writeval);
|
||||
else
|
||||
ret = regmap_read(sensor->hw->regmap, reg, readval);
|
||||
|
||||
iio_device_release_direct_mode(iio_dev);
|
||||
|
||||
return (ret < 0) ? ret : 0;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_get_odr(struct st_ilps22qs_sensor *sensor, u8 odr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < st_ilps22qs_odr_table.size; i++) {
|
||||
if (st_ilps22qs_odr_table.odr_avl[i].hz >= odr)
|
||||
break;
|
||||
}
|
||||
|
||||
return i == st_ilps22qs_odr_table.size ? -EINVAL : i;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_set_odr(struct st_ilps22qs_sensor *sensor, u8 odr)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = sensor->hw;
|
||||
u8 max_odr = odr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_ILPS22QS_SENSORS_NUM; i++) {
|
||||
if ((hw->enable_mask & BIT(i)) && (sensor->id != i)) {
|
||||
struct st_ilps22qs_sensor *temp;
|
||||
|
||||
temp = iio_priv(hw->iio_devs[i]);
|
||||
max_odr = max_t(u32, max_odr, temp->odr);
|
||||
}
|
||||
}
|
||||
|
||||
if (max_odr != hw->odr) {
|
||||
int err, ret;
|
||||
|
||||
ret = st_ilps22qs_get_odr(sensor, max_odr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
err = st_ilps22qs_update_locked(hw,
|
||||
st_ilps22qs_odr_table.reg.addr,
|
||||
st_ilps22qs_odr_table.reg.mask,
|
||||
st_ilps22qs_odr_table.odr_avl[ret].val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hw->odr = max_odr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* need hw->lock */
|
||||
static int st_ilps22qs_set_interleave(struct st_ilps22qs_sensor *sensor,
|
||||
bool enable)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = sensor->hw;
|
||||
int otherid = sensor->id == ST_ILPS22QS_PRESS ? ST_ILPS22QS_QVAR :
|
||||
ST_ILPS22QS_PRESS;
|
||||
int interleave;
|
||||
int err = 0;
|
||||
|
||||
/* both press / qvar enabling ? */
|
||||
mutex_lock(&hw->lock);
|
||||
interleave = (!!(hw->enable_mask & BIT(otherid))) && enable;
|
||||
if (interleave) {
|
||||
unsigned int ctrl1;
|
||||
|
||||
err = regmap_bulk_read(hw->regmap,
|
||||
ST_ILPS22QS_CTRL1_ADDR,
|
||||
&ctrl1, 1);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = regmap_update_bits(hw->regmap,
|
||||
ST_ILPS22QS_CTRL1_ADDR,
|
||||
ST_ILPS22QS_ODR_MASK, 0);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = regmap_update_bits(hw->regmap,
|
||||
ST_ILPS22QS_CTRL3_ADDR,
|
||||
ST_ILPS22QS_AH_QVAR_EN_MASK, 0);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = regmap_update_bits(hw->regmap, ST_ILPS22QS_CTRL3_ADDR,
|
||||
ST_ILPS22QS_AH_QVAR_P_AUTO_EN_MASK,
|
||||
ST_ILPS22QS_SHIFT_VAL(interleave,
|
||||
ST_ILPS22QS_AH_QVAR_P_AUTO_EN_MASK));
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = regmap_update_bits(hw->regmap, ST_ILPS22QS_CTRL1_ADDR,
|
||||
ST_ILPS22QS_ODR_MASK, ctrl1);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
} else if (hw->interleave) {
|
||||
err = regmap_update_bits(hw->regmap, ST_ILPS22QS_CTRL3_ADDR,
|
||||
ST_ILPS22QS_AH_QVAR_P_AUTO_EN_MASK, 0);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hw->interleave = interleave;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_hw_enable(struct st_ilps22qs_sensor *sensor, bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sensor->id) {
|
||||
case ST_ILPS22QS_QVAR:
|
||||
case ST_ILPS22QS_PRESS:
|
||||
ret = st_ilps22qs_set_interleave(sensor, enable);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_set_enable(struct st_ilps22qs_sensor *sensor,
|
||||
bool enable)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = sensor->hw;
|
||||
u8 odr = enable ? sensor->odr : 0;
|
||||
int err;
|
||||
|
||||
err = st_ilps22qs_hw_enable(sensor, enable);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_ilps22qs_set_odr(sensor, odr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
mutex_lock(&hw->lock);
|
||||
if (enable) {
|
||||
ktime_t ktime = ktime_set(0, 1000000000 / sensor->odr);
|
||||
|
||||
hrtimer_start(&sensor->hr_timer, ktime, HRTIMER_MODE_REL);
|
||||
sensor->ktime = ktime;
|
||||
hw->enable_mask |= BIT(sensor->id);
|
||||
} else {
|
||||
cancel_work_sync(&sensor->iio_work);
|
||||
hrtimer_cancel(&sensor->hr_timer);
|
||||
hw->enable_mask &= ~BIT(sensor->id);
|
||||
}
|
||||
|
||||
if (!hw->interleave) {
|
||||
err = regmap_update_bits(hw->regmap,
|
||||
ST_ILPS22QS_CTRL3_ADDR,
|
||||
ST_ILPS22QS_AH_QVAR_EN_MASK,
|
||||
ST_ILPS22QS_SHIFT_VAL(!!(hw->enable_mask & BIT(ST_ILPS22QS_QVAR)),
|
||||
ST_ILPS22QS_AH_QVAR_EN_MASK));
|
||||
}
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_init_sensors(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* soft reset the device on power on */
|
||||
err = st_ilps22qs_update_locked(hw, ST_ILPS22QS_CTRL2_ADDR,
|
||||
ST_ILPS22QS_SOFT_RESET_MASK, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
usleep_range(50, 60);
|
||||
|
||||
/* interleave disabled by default */
|
||||
hw->interleave = false;
|
||||
|
||||
/* enable BDU */
|
||||
return st_ilps22qs_update_locked(hw, ST_ILPS22QS_CTRL1_ADDR,
|
||||
ST_ILPS22QS_BDU_MASK, 1);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
st_ilps22qs_get_sampling_frequency_avail(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < st_ilps22qs_odr_table.size; i++) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
|
||||
st_ilps22qs_odr_table.odr_avl[i].hz);
|
||||
}
|
||||
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_read_raw(struct iio_dev *iio_dev,
|
||||
struct iio_chan_spec const *ch,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor = iio_priv(iio_dev);
|
||||
struct st_ilps22qs_hw *hw = sensor->hw;
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW: {
|
||||
u8 data[4] = {};
|
||||
int delay;
|
||||
|
||||
ret = iio_device_claim_direct_mode(iio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = st_ilps22qs_set_enable(sensor, true);
|
||||
if (ret < 0)
|
||||
goto read_error;
|
||||
|
||||
delay = 1000000 / sensor->odr;
|
||||
usleep_range(delay, 2 * delay);
|
||||
|
||||
ret = regmap_bulk_read(hw->regmap, ch->address, data,
|
||||
ch->scan_type.realbits >> 3);
|
||||
if (ret < 0)
|
||||
goto read_error;
|
||||
|
||||
switch (sensor->id) {
|
||||
case ST_ILPS22QS_PRESS:
|
||||
*val = (s32)get_unaligned_le32(data);
|
||||
break;
|
||||
case ST_ILPS22QS_TEMP:
|
||||
*val = (s16)get_unaligned_le16(data);
|
||||
break;
|
||||
case ST_ILPS22QS_QVAR:
|
||||
*val = (s32)get_unaligned_le32(data);
|
||||
break;
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
goto read_error;
|
||||
}
|
||||
|
||||
read_error:
|
||||
st_ilps22qs_set_enable(sensor, false);
|
||||
iio_device_release_direct_mode(iio_dev);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
}
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
switch (ch->type) {
|
||||
case IIO_TEMP:
|
||||
*val = 1000;
|
||||
*val2 = sensor->gain;
|
||||
ret = IIO_VAL_FRACTIONAL;
|
||||
break;
|
||||
case IIO_PRESSURE:
|
||||
*val = 0;
|
||||
*val2 = sensor->gain;
|
||||
ret = IIO_VAL_INT_PLUS_NANO;
|
||||
break;
|
||||
case IIO_ALTVOLTAGE:
|
||||
*val = 0;
|
||||
*val2 = sensor->gain;
|
||||
ret = IIO_VAL_INT_PLUS_NANO;
|
||||
break;
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*val = sensor->odr;
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st_ilps22qs_write_raw(struct iio_dev *iio_dev,
|
||||
struct iio_chan_spec const *ch,
|
||||
int val, int val2, long mask)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor = iio_priv(iio_dev);
|
||||
int ret;
|
||||
|
||||
ret = iio_device_claim_direct_mode(iio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
ret = st_ilps22qs_get_odr(sensor, val);
|
||||
if (ret < 0)
|
||||
goto exit_fail;
|
||||
|
||||
sensor->odr = st_ilps22qs_odr_table.odr_avl[ret].hz;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
exit_fail:
|
||||
iio_device_release_direct_mode(iio_dev);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_ilps22qs_get_sampling_frequency_avail);
|
||||
|
||||
static struct attribute *st_ilps22qs_press_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group st_ilps22qs_press_attribute_group = {
|
||||
.attrs = st_ilps22qs_press_attributes,
|
||||
};
|
||||
|
||||
static const struct iio_info st_ilps22qs_press_info = {
|
||||
.attrs = &st_ilps22qs_press_attribute_group,
|
||||
.read_raw = st_ilps22qs_read_raw,
|
||||
.write_raw = st_ilps22qs_write_raw,
|
||||
.debugfs_reg_access = st_ilps22qs_reg_access,
|
||||
};
|
||||
|
||||
static struct attribute *st_ilps22qs_temp_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group st_ilps22qs_temp_attribute_group = {
|
||||
.attrs = st_ilps22qs_temp_attributes,
|
||||
};
|
||||
|
||||
static const struct iio_info st_ilps22qs_temp_info = {
|
||||
.attrs = &st_ilps22qs_temp_attribute_group,
|
||||
.read_raw = st_ilps22qs_read_raw,
|
||||
.write_raw = st_ilps22qs_write_raw,
|
||||
.debugfs_reg_access = st_ilps22qs_reg_access,
|
||||
};
|
||||
|
||||
static struct attribute *st_ilps22qs_qvar_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group st_ilps22qs_qvar_attribute_group = {
|
||||
.attrs = st_ilps22qs_qvar_attributes,
|
||||
};
|
||||
|
||||
static const struct iio_info st_ilps22qs_qvar_info = {
|
||||
.attrs = &st_ilps22qs_qvar_attribute_group,
|
||||
.read_raw = st_ilps22qs_read_raw,
|
||||
.write_raw = st_ilps22qs_write_raw,
|
||||
.debugfs_reg_access = st_ilps22qs_reg_access,
|
||||
};
|
||||
|
||||
static int st_ilps22qs_preenable(struct iio_dev *iio_dev)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor = iio_priv(iio_dev);
|
||||
|
||||
return st_ilps22qs_set_enable(sensor, true);
|
||||
}
|
||||
|
||||
static int st_ilps22qs_postdisable(struct iio_dev *iio_dev)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor = iio_priv(iio_dev);
|
||||
|
||||
return st_ilps22qs_set_enable(sensor, false);
|
||||
}
|
||||
|
||||
static const struct iio_buffer_setup_ops st_ilps22qs_fifo_ops = {
|
||||
.preenable = st_ilps22qs_preenable,
|
||||
.postdisable = st_ilps22qs_postdisable,
|
||||
};
|
||||
|
||||
static void st_ilps22qs_disable_regulator_action(void *_data)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = _data;
|
||||
|
||||
regulator_disable(hw->vddio_supply);
|
||||
regulator_disable(hw->vdd_supply);
|
||||
}
|
||||
|
||||
static int st_ilps22qs_power_enable(struct st_ilps22qs_hw *hw)
|
||||
{
|
||||
int err;
|
||||
|
||||
hw->vdd_supply = devm_regulator_get(hw->dev, "vdd");
|
||||
if (IS_ERR(hw->vdd_supply)) {
|
||||
if (PTR_ERR(hw->vdd_supply) != -EPROBE_DEFER)
|
||||
dev_err(hw->dev, "Failed to get vdd regulator %d\n",
|
||||
(int)PTR_ERR(hw->vdd_supply));
|
||||
|
||||
return PTR_ERR(hw->vdd_supply);
|
||||
}
|
||||
|
||||
hw->vddio_supply = devm_regulator_get(hw->dev, "vddio");
|
||||
if (IS_ERR(hw->vddio_supply)) {
|
||||
if (PTR_ERR(hw->vddio_supply) != -EPROBE_DEFER)
|
||||
dev_err(hw->dev, "Failed to get vddio regulator %d\n",
|
||||
(int)PTR_ERR(hw->vddio_supply));
|
||||
|
||||
return PTR_ERR(hw->vddio_supply);
|
||||
}
|
||||
|
||||
err = regulator_enable(hw->vdd_supply);
|
||||
if (err) {
|
||||
dev_err(hw->dev, "Failed to enable vdd regulator: %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = regulator_enable(hw->vddio_supply);
|
||||
if (err) {
|
||||
regulator_disable(hw->vdd_supply);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_add_action_or_reset(hw->dev,
|
||||
st_ilps22qs_disable_regulator_action,
|
||||
hw);
|
||||
if (err) {
|
||||
dev_err(hw->dev,
|
||||
"Failed to setup regulator cleanup action %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* after the device is powered up, the ILPS22QS performs a 10 ms
|
||||
* boot procedure to load the trimming parameters
|
||||
*/
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct iio_dev *st_ilps22qs_alloc_iiodev(struct st_ilps22qs_hw *hw,
|
||||
enum st_ilps22qs_sensor_id id)
|
||||
{
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
struct iio_dev *iio_dev;
|
||||
|
||||
iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
|
||||
if (!iio_dev)
|
||||
return NULL;
|
||||
|
||||
iio_dev->modes = INDIO_DIRECT_MODE;
|
||||
iio_dev->dev.parent = hw->dev;
|
||||
|
||||
sensor = iio_priv(iio_dev);
|
||||
sensor->hw = hw;
|
||||
sensor->id = id;
|
||||
sensor->odr = st_ilps22qs_odr_table.odr_avl[0].hz;
|
||||
|
||||
switch (id) {
|
||||
case ST_ILPS22QS_PRESS:
|
||||
sensor->gain = ST_ILPS22QS_PRESS_FS_AVL_GAIN;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_ILPS22QS_DEV_NAME "_press");
|
||||
iio_dev->channels = st_ilps22qs_press_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_ilps22qs_press_channels);
|
||||
iio_dev->info = &st_ilps22qs_press_info;
|
||||
break;
|
||||
case ST_ILPS22QS_TEMP:
|
||||
sensor->gain = ST_ILPS22QS_TEMP_FS_AVL_GAIN;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_ILPS22QS_DEV_NAME "_temp");
|
||||
iio_dev->channels = st_ilps22qs_temp_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_ilps22qs_temp_channels);
|
||||
iio_dev->info = &st_ilps22qs_temp_info;
|
||||
break;
|
||||
case ST_ILPS22QS_QVAR:
|
||||
sensor->gain = ST_ILPS22QS_QVAR_FS_AVL_GAIN;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_ILPS22QS_DEV_NAME "_qvar");
|
||||
iio_dev->channels = st_ilps22qs_qvar_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_ilps22qs_qvar_channels);
|
||||
iio_dev->info = &st_ilps22qs_qvar_info;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iio_dev->name = sensor->name;
|
||||
|
||||
/* configure sensor hrtimer */
|
||||
hrtimer_init(&sensor->hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
sensor->hr_timer.function = &st_ilps22qs_poll_function_read;
|
||||
INIT_WORK(&sensor->iio_work, st_ilps22qs_poll_function_work);
|
||||
|
||||
return iio_dev;
|
||||
}
|
||||
|
||||
int st_ilps22qs_probe(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw;
|
||||
int err, i;
|
||||
|
||||
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
|
||||
if (!hw)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&hw->lock);
|
||||
|
||||
dev_set_drvdata(dev, (void *)hw);
|
||||
hw->dev = dev;
|
||||
hw->regmap = regmap;
|
||||
|
||||
err = st_ilps22qs_power_enable(hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = st_ilps22qs_check_whoami(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_ilps22qs_init_sensors(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < ST_ILPS22QS_SENSORS_NUM; i++) {
|
||||
|
||||
#if KERNEL_VERSION(5, 13, 0) > LINUX_VERSION_CODE
|
||||
struct iio_buffer *buffer;
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
|
||||
hw->iio_devs[i] = st_ilps22qs_alloc_iiodev(hw, i);
|
||||
if (!hw->iio_devs[i])
|
||||
return -ENOMEM;
|
||||
|
||||
#if KERNEL_VERSION(5, 19, 0) <= LINUX_VERSION_CODE
|
||||
err = devm_iio_kfifo_buffer_setup(hw->dev,
|
||||
hw->iio_devs[i],
|
||||
&st_ilps22qs_fifo_ops);
|
||||
if (err)
|
||||
return err;
|
||||
#elif KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
|
||||
err = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i],
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&st_ilps22qs_fifo_ops);
|
||||
if (err)
|
||||
return err;
|
||||
#else /* LINUX_VERSION_CODE */
|
||||
buffer = devm_iio_kfifo_allocate(hw->dev);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
iio_device_attach_buffer(hw->iio_devs[i], buffer);
|
||||
hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
|
||||
hw->iio_devs[i]->setup_ops = &st_ilps22qs_fifo_ops;
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
|
||||
err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = st_ilps22qs_allocate_workqueue(hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dev_info(dev, "device probed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(st_ilps22qs_probe);
|
||||
|
||||
int st_ilps22qs_remove(struct device *dev)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = dev_get_drvdata(dev);
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_ILPS22QS_SENSORS_NUM; i++) {
|
||||
int err;
|
||||
|
||||
if (!hw->iio_devs[i])
|
||||
continue;
|
||||
|
||||
sensor = iio_priv(hw->iio_devs[i]);
|
||||
if (!(hw->enable_mask & BIT(sensor->id)))
|
||||
continue;
|
||||
|
||||
err = st_ilps22qs_set_enable(sensor, false);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
st_ilps22qs_flush_works(hw);
|
||||
st_ilps22qs_destroy_workqueue(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(st_ilps22qs_remove);
|
||||
|
||||
static int __maybe_unused st_ilps22qs_suspend(struct device *dev)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = dev_get_drvdata(dev);
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_ILPS22QS_SENSORS_NUM; i++) {
|
||||
int err;
|
||||
|
||||
if (!hw->iio_devs[i])
|
||||
continue;
|
||||
|
||||
sensor = iio_priv(hw->iio_devs[i]);
|
||||
if (!(hw->enable_mask & BIT(sensor->id)))
|
||||
continue;
|
||||
|
||||
err = st_ilps22qs_set_odr(sensor, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cancel_work_sync(&sensor->iio_work);
|
||||
hrtimer_cancel(&sensor->hr_timer);
|
||||
}
|
||||
|
||||
dev_info(dev, "Suspending device\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused st_ilps22qs_resume(struct device *dev)
|
||||
{
|
||||
struct st_ilps22qs_hw *hw = dev_get_drvdata(dev);
|
||||
struct st_ilps22qs_sensor *sensor;
|
||||
int i;
|
||||
|
||||
dev_info(dev, "Resuming device\n");
|
||||
|
||||
for (i = 0; i < ST_ILPS22QS_SENSORS_NUM; i++) {
|
||||
int err;
|
||||
|
||||
if (!hw->iio_devs[i])
|
||||
continue;
|
||||
|
||||
sensor = iio_priv(hw->iio_devs[i]);
|
||||
if (!(hw->enable_mask & BIT(sensor->id)))
|
||||
continue;
|
||||
|
||||
err = st_ilps22qs_set_enable(sensor, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct dev_pm_ops st_ilps22qs_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(st_ilps22qs_suspend, st_ilps22qs_resume)
|
||||
};
|
||||
EXPORT_SYMBOL(st_ilps22qs_pm_ops);
|
||||
|
||||
MODULE_AUTHOR("MEMS Software Solutions Team");
|
||||
MODULE_DESCRIPTION("STMicroelectronics ilps22qs driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics ilps22qs i2c driver
|
||||
*
|
||||
* Copyright 2023 STMicroelectronics Inc.
|
||||
*
|
||||
* MEMS Software Solutions Team
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "st_ilps22qs.h"
|
||||
|
||||
static const struct regmap_config st_ilps22qs_i2c_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
#if KERNEL_VERSION(6, 2, 0) <= LINUX_VERSION_CODE
|
||||
static int st_ilps22qs_i2c_probe(struct i2c_client *client)
|
||||
#else /* LINUX_VERSION_CODE */
|
||||
static int st_ilps22qs_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &st_ilps22qs_i2c_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to register i2c regmap %d\n",
|
||||
(int)PTR_ERR(regmap));
|
||||
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return st_ilps22qs_probe(&client->dev, regmap);
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
|
||||
static void st_ilps22qs_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
st_ilps22qs_remove(&client->dev);
|
||||
}
|
||||
#else /* LINUX_VERSION_CODE */
|
||||
static int st_ilps22qs_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return st_ilps22qs_remove(&client->dev);
|
||||
}
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
|
||||
static const struct i2c_device_id st_ilps22qs_ids[] = {
|
||||
{ ST_ILPS22QS_DEV_NAME },
|
||||
{ ST_ILPS28QSW_DEV_NAME },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_ilps22qs_ids);
|
||||
|
||||
static const struct of_device_id st_ilps22qs_id_table[] = {
|
||||
{ .compatible = "st," ST_ILPS22QS_DEV_NAME },
|
||||
{ .compatible = "st," ST_ILPS28QSW_DEV_NAME },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_ilps22qs_id_table);
|
||||
|
||||
static struct i2c_driver st_ilps22qs_i2c_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "st_" ST_ILPS22QS_DEV_NAME "_i2c",
|
||||
.pm = &st_ilps22qs_pm_ops,
|
||||
.of_match_table = of_match_ptr(st_ilps22qs_id_table),
|
||||
},
|
||||
.probe = st_ilps22qs_i2c_probe,
|
||||
.remove = st_ilps22qs_i2c_remove,
|
||||
.id_table = st_ilps22qs_ids,
|
||||
};
|
||||
module_i2c_driver(st_ilps22qs_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("MEMS Software Solutions Team");
|
||||
MODULE_DESCRIPTION("STMicroelectronics ilps22qs i2c driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
config INPUT_LSM303AGR
|
||||
tristate "STM LSM303AGR sensor"
|
||||
depends on I2C && SYSFS
|
||||
help
|
||||
This driver support the STMicroelectronics LSM303AGR sensor.
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for the input misc lsm303agr driver.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
obj-$(CONFIG_INPUT_LSM303AGR) += lsm303agr_acc.o lsm303agr_mag.o lsm303agr_acc_i2c.o lsm303agr_mag_i2c.o
|
||||
@@ -0,0 +1,885 @@
|
||||
/*
|
||||
* STMicroelectronics lsm303agr_acc.c driver
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Giuseppe Barba <giuseppe.barba@st.com>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "lsm303agr_core.h"
|
||||
|
||||
#define LSM303AGR_ACC_DEV_NAME "lsm303agr_acc"
|
||||
|
||||
#define LSM303AGR_ACC_MIN_POLL_PERIOD_MS 1
|
||||
|
||||
/* I2C slave address */
|
||||
#define LSM303AGR_ACC_I2C_SAD 0x29
|
||||
/* Accelerometer Sensor Full Scale */
|
||||
#define LSM303AGR_ACC_FS_MSK 0x20
|
||||
#define LSM303AGR_ACC_G_2G 0x00
|
||||
#define LSM303AGR_ACC_G_8G 0x20
|
||||
|
||||
#define AXISDATA_REG 0x28
|
||||
#define WHOAMI_LSM303AGR_ACC 0x33
|
||||
#define WHO_AM_I 0x0F
|
||||
#define CTRL_REG1 0x20
|
||||
#define CTRL_REG2 0x23
|
||||
|
||||
#define LSM303AGR_ACC_PM_OFF 0x00
|
||||
#define LSM303AGR_ACC_ENABLE_ALL_AXIS 0x07
|
||||
#define LSM303AGR_ACC_AXIS_MSK 0x07
|
||||
#define LSM303AGR_ACC_ODR_MSK 0xf0
|
||||
#define LSM303AGR_ACC_LP_MSK 0X08
|
||||
#define LSM303AGR_ACC_HR_MSK 0X08
|
||||
|
||||
/* device opmode */
|
||||
enum lsm303agr_acc_opmode {
|
||||
LSM303AGR_ACC_OPMODE_NORMAL,
|
||||
LSM303AGR_ACC_OPMODE_HR,
|
||||
LSM303AGR_ACC_OPMODE_LP,
|
||||
};
|
||||
|
||||
/* Device sensitivities [ug/digit] */
|
||||
#define LSM303AGR_ACC_SENSITIVITY_NORMAL_2G 3900
|
||||
#define LSM303AGR_ACC_SENSITIVITY_NORMAL_4G 7820
|
||||
#define LSM303AGR_ACC_SENSITIVITY_NORMAL_8G 15630
|
||||
#define LSM303AGR_ACC_SENSITIVITY_NORMAL_16G 46900
|
||||
#define LSM303AGR_ACC_SENSITIVITY_HR_2G 980
|
||||
#define LSM303AGR_ACC_SENSITIVITY_HR_4G 1950
|
||||
#define LSM303AGR_ACC_SENSITIVITY_HR_8G 3900
|
||||
#define LSM303AGR_ACC_SENSITIVITY_HR_16G 11720
|
||||
#define LSM303AGR_ACC_SENSITIVITY_LP_2G 15630
|
||||
#define LSM303AGR_ACC_SENSITIVITY_LP_4G 31260
|
||||
#define LSM303AGR_ACC_SENSITIVITY_LP_8G 62520
|
||||
#define LSM303AGR_ACC_SENSITIVITY_LP_16G 187580
|
||||
|
||||
/* Device shift values */
|
||||
#define LSM303AGR_ACC_SHIFT_NORMAL_MODE 6
|
||||
#define LSM303AGR_ACC_SHIFT_HR_MODE 4
|
||||
#define LSM303AGR_ACC_SHIFT_LP_MODE 8
|
||||
|
||||
const struct {
|
||||
u16 shift;
|
||||
u32 sensitivity[4];
|
||||
} lsm303agr_acc_opmode_table[] = {
|
||||
{
|
||||
/* normal mode */
|
||||
LSM303AGR_ACC_SHIFT_NORMAL_MODE,
|
||||
{
|
||||
LSM303AGR_ACC_SENSITIVITY_NORMAL_2G,
|
||||
LSM303AGR_ACC_SENSITIVITY_NORMAL_4G,
|
||||
LSM303AGR_ACC_SENSITIVITY_NORMAL_8G,
|
||||
LSM303AGR_ACC_SENSITIVITY_NORMAL_16G
|
||||
}
|
||||
},
|
||||
{
|
||||
/* hr mode */
|
||||
LSM303AGR_ACC_SHIFT_HR_MODE,
|
||||
{
|
||||
LSM303AGR_ACC_SENSITIVITY_HR_2G,
|
||||
LSM303AGR_ACC_SENSITIVITY_HR_4G,
|
||||
LSM303AGR_ACC_SENSITIVITY_HR_8G,
|
||||
LSM303AGR_ACC_SENSITIVITY_HR_16G
|
||||
}
|
||||
},
|
||||
{
|
||||
/* lp mode */
|
||||
LSM303AGR_ACC_SHIFT_LP_MODE,
|
||||
{
|
||||
LSM303AGR_ACC_SENSITIVITY_LP_2G,
|
||||
LSM303AGR_ACC_SENSITIVITY_LP_4G,
|
||||
LSM303AGR_ACC_SENSITIVITY_LP_8G,
|
||||
LSM303AGR_ACC_SENSITIVITY_LP_16G
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define LSM303AGR_ACC_ODR10 0x20 /* 10Hz output data rate */
|
||||
#define LSM303AGR_ACC_ODR50 0x40 /* 50Hz output data rate */
|
||||
#define LSM303AGR_ACC_ODR100 0x50 /* 100Hz output data rate */
|
||||
#define LSM303AGR_ACC_ODR200 0x60 /* 200Hz output data rate */
|
||||
|
||||
/* read and write with mask a given register */
|
||||
static int lsm303agr_acc_write_data_with_mask(struct lsm303agr_common_data *cdata,
|
||||
u8 reg_addr, u8 mask, u8 *data)
|
||||
{
|
||||
int err;
|
||||
u8 new_data, old_data = 0;
|
||||
|
||||
err = cdata->tf->read(cdata->dev, reg_addr, 1, &old_data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
new_data = ((old_data & (~mask)) | ((*data) & mask));
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
dev_info(cdata->dev, "%s %02x o=%02x d=%02x n=%02x\n",
|
||||
LSM303AGR_ACC_DEV_NAME, reg_addr, old_data, *data, new_data);
|
||||
#endif
|
||||
|
||||
/* Save for caller usage the data that is about to be written */
|
||||
*data = new_data;
|
||||
|
||||
if (new_data == old_data)
|
||||
return 1;
|
||||
|
||||
return cdata->tf->write(cdata->dev, reg_addr, 1, &new_data);
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_input_init(struct lsm303agr_sensor_data *sdata,
|
||||
const char* description)
|
||||
{
|
||||
int err;
|
||||
|
||||
sdata->input_dev = input_allocate_device();
|
||||
if (!sdata->input_dev) {
|
||||
dev_err(sdata->cdata->dev, "input device allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sdata->input_dev->name = description;
|
||||
sdata->input_dev->id.bustype = sdata->cdata->bus_type;
|
||||
sdata->input_dev->dev.parent = sdata->cdata->dev;
|
||||
|
||||
input_set_drvdata(sdata->input_dev, sdata);
|
||||
|
||||
/* Set the input event characteristics of the probed sensor driver */
|
||||
set_bit(INPUT_EVENT_TYPE, sdata->input_dev->evbit);
|
||||
set_bit(INPUT_EVENT_TIME_MSB, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_TIME_LSB, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_X, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_Y, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_Z, sdata->input_dev->mscbit);
|
||||
|
||||
err = input_register_device(sdata->input_dev);
|
||||
if (err) {
|
||||
dev_err(sdata->cdata->dev,
|
||||
"unable to register input device %s\n",
|
||||
sdata->input_dev->name);
|
||||
input_free_device(sdata->input_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
unsigned int cutoff_ms;
|
||||
unsigned int mask;
|
||||
} lsm303agr_acc_odr_table[] = {
|
||||
{ 5, LSM303AGR_ACC_ODR200 }, /* ODR = 200Hz */
|
||||
{ 10, LSM303AGR_ACC_ODR100 }, /* ODR = 100Hz */
|
||||
{ 20, LSM303AGR_ACC_ODR50 }, /* ODR = 50Hz */
|
||||
{ 100, LSM303AGR_ACC_ODR10 }, /* ODR = 10Hz */
|
||||
};
|
||||
|
||||
static int lsm303agr_acc_hw_init(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
int err;
|
||||
u8 buf, wai = 0;
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
pr_info("%s: hw init start\n", LSM303AGR_ACC_DEV_NAME);
|
||||
#endif
|
||||
|
||||
err = cdata->tf->read(cdata->dev, WHO_AM_I, 1, &wai);
|
||||
if (err < 0) {
|
||||
dev_warn(cdata->dev, "Error reading WHO_AM_I\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (wai != WHOAMI_LSM303AGR_ACC) {
|
||||
dev_err(cdata->dev,
|
||||
"device unknown (0x%02x-0x%02x)\n",
|
||||
WHOAMI_LSM303AGR_ACC, wai);
|
||||
err = -1; /* choose the right coded error */
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf = cdata->sensors[LSM303AGR_ACC_SENSOR].c_odr;
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG1,
|
||||
LSM303AGR_ACC_ODR_MSK, &buf);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
cdata->hw_initialized = 1;
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
pr_info("%s: hw init done\n", LSM303AGR_ACC_DEV_NAME);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cdata->hw_initialized = 0;
|
||||
dev_err(cdata->dev, "hw init error 0x%02x: %d\n", buf, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lsm303agr_acc_device_power_off(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
int err;
|
||||
u8 buf = LSM303AGR_ACC_PM_OFF;
|
||||
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG1,
|
||||
LSM303AGR_ACC_ODR_MSK, &buf);
|
||||
if (err < 0)
|
||||
dev_err(cdata->dev, "soft power off failed: %d\n", err);
|
||||
|
||||
if (cdata->hw_initialized)
|
||||
cdata->hw_initialized = 0;
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_device_power_on(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
if (!cdata->hw_initialized) {
|
||||
int err = lsm303agr_acc_hw_init(cdata);
|
||||
if (err < 0) {
|
||||
lsm303agr_acc_device_power_off(cdata);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_update_fs_range(struct lsm303agr_common_data *cdata,
|
||||
u8 new_fs_range)
|
||||
{
|
||||
int err;
|
||||
u8 indx;
|
||||
u16 opmode;
|
||||
unsigned int new_sensitivity;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
opmode = sdata->opmode;
|
||||
|
||||
switch (new_fs_range) {
|
||||
case LSM303AGR_ACC_G_2G:
|
||||
indx = 0;
|
||||
break;
|
||||
case LSM303AGR_ACC_G_8G:
|
||||
indx = 2;
|
||||
break;
|
||||
default:
|
||||
dev_err(cdata->dev, "invalid fs range requested: %u\n",
|
||||
new_fs_range);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Updates configuration register 4 which contains fs range setting */
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG2,
|
||||
LSM303AGR_ACC_FS_MSK,
|
||||
&new_fs_range);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
new_sensitivity = lsm303agr_acc_opmode_table[opmode].sensitivity[indx];
|
||||
sdata->sensitivity = new_sensitivity;
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
dev_info(cdata->dev, "%s shift=%d, sens=%d, opm=%d\n",
|
||||
LSM303AGR_ACC_DEV_NAME, sdata->shift, sdata->sensitivity,
|
||||
sdata->opmode);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
error:
|
||||
dev_err(cdata->dev, "update fs range failed %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_update_odr(struct lsm303agr_common_data *cdata,
|
||||
int poll_interval)
|
||||
{
|
||||
u8 buf;
|
||||
int i, err = -1;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
/**
|
||||
* Following, looks for the longest possible odr
|
||||
* interval od -x /dev/input/event0 scrolling the
|
||||
* odr_table vector from the end (shortest interval) backward (longest
|
||||
* interval), to support the poll_interval requested by the system.
|
||||
* It must be the longest interval lower then the poll interval
|
||||
*/
|
||||
for (i = ARRAY_SIZE(lsm303agr_acc_odr_table) - 1; i >= 0; i--) {
|
||||
if ((lsm303agr_acc_odr_table[i].cutoff_ms <= poll_interval) ||
|
||||
(i == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
/* also save requested odr */
|
||||
buf = (sdata->c_odr = lsm303agr_acc_odr_table[i].mask) |
|
||||
LSM303AGR_ACC_ENABLE_ALL_AXIS;
|
||||
|
||||
/*
|
||||
* If device is currently enabled, we need to write new
|
||||
* configuration out to it
|
||||
*/
|
||||
if (atomic_read(&cdata->enabled)) {
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG1,
|
||||
LSM303AGR_ACC_ODR_MSK |
|
||||
LSM303AGR_ACC_AXIS_MSK,
|
||||
&buf);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
dev_info(cdata->dev, "update odr to 0x%02x,0x%02x: %d\n",
|
||||
CTRL_REG1, buf, err);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
|
||||
error:
|
||||
dev_err(cdata->dev, "update odr failed 0x%02x,0x%02x: %d\n",
|
||||
CTRL_REG1, buf, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_update_opmode(struct lsm303agr_common_data *cdata,
|
||||
unsigned short opmode)
|
||||
{
|
||||
int err;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
u8 lp = 0, hr = 0, indx = 0;
|
||||
|
||||
switch (opmode) {
|
||||
case LSM303AGR_ACC_OPMODE_NORMAL:
|
||||
break;
|
||||
case LSM303AGR_ACC_OPMODE_HR:
|
||||
hr = (1 << __ffs(LSM303AGR_ACC_LP_MSK));
|
||||
break;
|
||||
case LSM303AGR_ACC_OPMODE_LP:
|
||||
lp = (1 << __ffs(LSM303AGR_ACC_HR_MSK));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set LP bit in CTRL_REG1 */
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG1,
|
||||
LSM303AGR_ACC_LP_MSK, &lp);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* Set HR bit in CTRL_REG4 */
|
||||
err = lsm303agr_acc_write_data_with_mask(cdata, CTRL_REG2,
|
||||
LSM303AGR_ACC_HR_MSK,
|
||||
&hr);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* Change platform data */
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
sdata->opmode = opmode;
|
||||
sdata->shift = lsm303agr_acc_opmode_table[opmode].shift;
|
||||
|
||||
switch (sdata->fs_range) {
|
||||
case LSM303AGR_ACC_G_2G:
|
||||
indx = 0;
|
||||
break;
|
||||
case LSM303AGR_ACC_G_8G:
|
||||
indx = 2;
|
||||
break;
|
||||
}
|
||||
sdata->sensitivity = lsm303agr_acc_opmode_table[opmode].sensitivity[indx];
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
dev_info(cdata->dev, "%s shift=%d, sens=%d, opm=%d\n",
|
||||
LSM303AGR_ACC_DEV_NAME, sdata->shift, sdata->sensitivity,
|
||||
sdata->opmode);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
|
||||
error:
|
||||
dev_err(cdata->dev, "update opmode failed: %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
lsm303agr_acc_get_acceleration_data(struct lsm303agr_common_data *cdata, int *xyz)
|
||||
{
|
||||
int err;
|
||||
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
|
||||
u8 acc_data[6];
|
||||
/* x,y,z hardware data */
|
||||
u32 sensitivity, shift;
|
||||
|
||||
err = cdata->tf->read(cdata->dev, AXISDATA_REG, 6, acc_data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Get the current sensitivity and shift values */
|
||||
sensitivity = cdata->sensors[LSM303AGR_ACC_SENSOR].sensitivity;
|
||||
shift = cdata->sensors[LSM303AGR_ACC_SENSOR].shift;
|
||||
|
||||
/* Transform LSBs into ug */
|
||||
xyz[0] = (s32)((s16)(acc_data[0] | (acc_data[1] << 8)) >> shift) * sensitivity;
|
||||
xyz[1] = (s32)((s16)(acc_data[2] | (acc_data[3] << 8)) >> shift) * sensitivity;
|
||||
xyz[2] = (s32)((s16)(acc_data[4] | (acc_data[5] << 8)) >> shift) * sensitivity;
|
||||
|
||||
#ifdef LSM303AGR_ACC_DEBUG
|
||||
dev_info(cdata->dev, "%s read x=%d, y=%d, z=%d\n",
|
||||
LSM303AGR_ACC_DEV_NAME, xyz[0], xyz[1], xyz[2]);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lsm303agr_acc_report_values(struct lsm303agr_common_data *cdata,
|
||||
int *xyz, s64 timestamp)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_X, xyz[0]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_Y, xyz[1]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_Z, xyz[2]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_TIME_MSB,
|
||||
timestamp >> 32);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_TIME_LSB,
|
||||
timestamp & 0xffffffff);
|
||||
input_sync(sdata->input_dev);
|
||||
}
|
||||
|
||||
int lsm303agr_acc_enable(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
if (!atomic_cmpxchg(&cdata->enabled, 0, 1)) {
|
||||
int err;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
err = lsm303agr_acc_device_power_on(cdata);
|
||||
if (err < 0) {
|
||||
atomic_set(&cdata->enabled, 0);
|
||||
return err;
|
||||
}
|
||||
schedule_delayed_work(&sdata->input_work,
|
||||
msecs_to_jiffies(sdata->poll_interval));
|
||||
|
||||
mutex_unlock(&cdata->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_acc_enable);
|
||||
|
||||
int lsm303agr_acc_disable(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
if (atomic_cmpxchg(&cdata->enabled, 1, 0)) {
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
cancel_delayed_work_sync(&sdata->input_work);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
lsm303agr_acc_device_power_off(cdata);
|
||||
mutex_unlock(&cdata->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_acc_disable);
|
||||
|
||||
static ssize_t attr_get_sched_num_acc(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int val;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
val = cdata->sensors[LSM303AGR_ACC_SENSOR].schedule_num;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_sched_num_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long sched_num;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
if (kstrtoul(buf, 10, &sched_num))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
cdata->sensors[LSM303AGR_ACC_SENSOR].schedule_num = sched_num;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t attr_get_polling_rate_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int val;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
val = cdata->sensors[LSM303AGR_ACC_SENSOR].poll_interval;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_polling_rate_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long interval_ms;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
if (kstrtoul(buf, 10, &interval_ms))
|
||||
return -EINVAL;
|
||||
|
||||
if (!interval_ms)
|
||||
return -EINVAL;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
interval_ms = max_t(unsigned int, (unsigned int)interval_ms,
|
||||
sdata->min_interval);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
sdata->poll_interval = interval_ms;
|
||||
lsm303agr_acc_update_odr(cdata, interval_ms);
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t attr_get_range_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
char range = 2;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
switch (sdata->fs_range) {
|
||||
case LSM303AGR_ACC_G_2G:
|
||||
range = 2;
|
||||
break;
|
||||
case LSM303AGR_ACC_G_8G:
|
||||
range = 8;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", range);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_range_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
u8 range;
|
||||
int err;
|
||||
unsigned long val;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
if (kstrtoul(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
switch (val) {
|
||||
case 2:
|
||||
range = LSM303AGR_ACC_G_2G;
|
||||
break;
|
||||
case 8:
|
||||
range = LSM303AGR_ACC_G_8G;
|
||||
break;
|
||||
default:
|
||||
dev_err(cdata->dev,
|
||||
"invalid range request: %lu, discarded\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
err = lsm303agr_acc_update_fs_range(cdata, range);
|
||||
if (err < 0) {
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
sdata->fs_range = range;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
dev_info(cdata->dev, "range set to: %lu g\n", val);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t attr_get_opmode_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
char opmode;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
opmode = cdata->sensors[LSM303AGR_ACC_SENSOR].opmode;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", opmode);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_opmode_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int err;
|
||||
u16 opmode;
|
||||
unsigned long val;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
if (kstrtoul(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if argument is valid opmode */
|
||||
switch (val) {
|
||||
case LSM303AGR_ACC_OPMODE_NORMAL:
|
||||
case LSM303AGR_ACC_OPMODE_HR:
|
||||
case LSM303AGR_ACC_OPMODE_LP:
|
||||
opmode = val;
|
||||
break;
|
||||
default:
|
||||
dev_err(cdata->dev,
|
||||
"invalid range request: %lu, discarded\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
err = lsm303agr_acc_update_opmode(cdata, opmode);
|
||||
if (err < 0) {
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
dev_info(cdata->dev, "opmode set to: %u\n", opmode);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t attr_get_enable_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
int val = atomic_read(&cdata->enabled);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_enable_acc(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
unsigned long val;
|
||||
|
||||
if (kstrtoul(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
lsm303agr_acc_enable(cdata);
|
||||
else
|
||||
lsm303agr_acc_disable(cdata);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct device_attribute attributes[] = {
|
||||
|
||||
__ATTR(pollrate_ms, 0664, attr_get_polling_rate_acc,
|
||||
attr_set_polling_rate_acc),
|
||||
__ATTR(range, 0664, attr_get_range_acc, attr_set_range_acc),
|
||||
__ATTR(opmode, 0664, attr_get_opmode_acc, attr_set_opmode_acc),
|
||||
__ATTR(enable_device, 0664, attr_get_enable_acc, attr_set_enable_acc),
|
||||
__ATTR(schedule_num, 0664, attr_get_sched_num_acc,
|
||||
attr_set_sched_num_acc),
|
||||
};
|
||||
|
||||
static int create_sysfs_interfaces(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attributes); i++)
|
||||
if (device_create_file(dev, attributes + i))
|
||||
goto error;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (; i >= 0; i--)
|
||||
device_remove_file(dev, attributes + i);
|
||||
|
||||
dev_err(dev, "%s:Unable to create interface\n", __func__);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int remove_sysfs_interfaces(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attributes); i++)
|
||||
device_remove_file(dev, attributes + i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lsm303agr_acc_input_work_func(struct work_struct *work)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
int err, xyz[3] = {};
|
||||
|
||||
sdata = container_of((struct delayed_work *)work,
|
||||
struct lsm303agr_sensor_data, input_work);
|
||||
cdata = sdata->cdata;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
sdata->schedule_num++;
|
||||
err = lsm303agr_acc_get_acceleration_data(cdata, xyz);
|
||||
if (err < 0)
|
||||
dev_err(cdata->dev, "get_acceleration_data failed\n");
|
||||
else
|
||||
lsm303agr_acc_report_values(cdata, xyz, lsm303agr_get_time_ns());
|
||||
|
||||
schedule_delayed_work(&sdata->input_work, msecs_to_jiffies(
|
||||
sdata->poll_interval));
|
||||
mutex_unlock(&cdata->lock);
|
||||
}
|
||||
|
||||
static void lsm303agr_acc_input_cleanup(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
input_unregister_device(sdata->input_dev);
|
||||
input_free_device(sdata->input_dev);
|
||||
}
|
||||
|
||||
int lsm303agr_acc_probe(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
int err;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* init sensor data structure */
|
||||
sdata = &cdata->sensors[LSM303AGR_ACC_SENSOR];
|
||||
|
||||
sdata->cdata = cdata;
|
||||
sdata->poll_interval = 100;
|
||||
sdata->min_interval = LSM303AGR_ACC_MIN_POLL_PERIOD_MS;
|
||||
|
||||
err = lsm303agr_acc_device_power_on(cdata);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "power on failed: %d\n", err);
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
atomic_set(&cdata->enabled, 1);
|
||||
|
||||
err = lsm303agr_acc_update_fs_range(cdata, LSM303AGR_ACC_G_2G);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "update_fs_range failed\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
err = lsm303agr_acc_update_odr(cdata, sdata->poll_interval);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "update_odr failed\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
err = lsm303agr_acc_update_opmode(cdata, LSM303AGR_ACC_OPMODE_NORMAL);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "update_opmode failed\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
err = lsm303agr_acc_input_init(sdata, LSM303AGR_ACC_DEV_NAME);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "input init failed\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
INIT_DELAYED_WORK(&sdata->input_work, lsm303agr_acc_input_work_func);
|
||||
|
||||
|
||||
err = create_sysfs_interfaces(cdata->dev);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev,
|
||||
"device LSM303AGR_ACC_DEV_NAME sysfs register failed\n");
|
||||
goto err_input_cleanup;
|
||||
}
|
||||
|
||||
lsm303agr_acc_device_power_off(cdata);
|
||||
|
||||
/* As default, do not report information */
|
||||
atomic_set(&cdata->enabled, 0);
|
||||
|
||||
dev_info(cdata->dev, "%s: probed\n", LSM303AGR_ACC_DEV_NAME);
|
||||
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_input_cleanup:
|
||||
lsm303agr_acc_input_cleanup(cdata);
|
||||
err_power_off:
|
||||
lsm303agr_acc_device_power_off(cdata);
|
||||
mutex_unlock(&cdata->lock);
|
||||
pr_err("%s: Driver Init failed\n", LSM303AGR_ACC_DEV_NAME);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_acc_probe);
|
||||
|
||||
void lsm303agr_acc_remove(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
lsm303agr_acc_disable(cdata);
|
||||
lsm303agr_acc_input_cleanup(cdata);
|
||||
remove_sysfs_interfaces(cdata->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_acc_remove);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* STMicroelectronics lsm303agr_acc_i2c.c driver
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Giuseppe Barba <giuseppe.barba@st.com>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "lsm303agr_core.h"
|
||||
|
||||
#define I2C_AUTO_INCREMENT 0x80
|
||||
|
||||
/* XXX: caller must hold cdata->lock */
|
||||
static int lsm303agr_acc_i2c_read(struct device *dev, u8 reg_addr, int len,
|
||||
u8 *data)
|
||||
{
|
||||
struct i2c_msg msg[2];
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (len > 1)
|
||||
reg_addr |= I2C_AUTO_INCREMENT;
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = client->flags;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = ®_addr;
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = client->flags | I2C_M_RD;
|
||||
msg[1].len = len;
|
||||
msg[1].buf = data;
|
||||
|
||||
return i2c_transfer(client->adapter, msg, 2);
|
||||
}
|
||||
|
||||
/* XXX: caller must hold cdata->lock */
|
||||
static int lsm303agr_acc_i2c_write(struct device *dev, u8 reg_addr, int len,
|
||||
u8 *data)
|
||||
{
|
||||
u8 send[len + 1];
|
||||
struct i2c_msg msg;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (len > 1)
|
||||
reg_addr |= I2C_AUTO_INCREMENT;
|
||||
|
||||
send[0] = reg_addr;
|
||||
memcpy(&send[1], data, len * sizeof(u8));
|
||||
len++;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = client->flags;
|
||||
msg.len = len;
|
||||
msg.buf = send;
|
||||
|
||||
return i2c_transfer(client->adapter, &msg, 1);
|
||||
}
|
||||
|
||||
/* I2C IO routines */
|
||||
static const struct lsm303agr_transfer_function lsm303agr_acc_i2c_tf = {
|
||||
.write = lsm303agr_acc_i2c_write,
|
||||
.read = lsm303agr_acc_i2c_read,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int lsm303agr_acc_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
if (cdata->on_before_suspend)
|
||||
return lsm303agr_acc_enable(cdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsm303agr_acc_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
cdata->on_before_suspend = atomic_read(&cdata->enabled);
|
||||
return lsm303agr_acc_disable(cdata);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(lsm303agr_acc_pm_ops,
|
||||
lsm303agr_acc_suspend,
|
||||
lsm303agr_acc_resume);
|
||||
|
||||
#define LSM303AGR_ACC_PM_OPS (&lsm303agr_acc_pm_ops)
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
#define LSM303AGR_ACC_PM_OPS NULL
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static int lsm303agr_acc_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int err;
|
||||
struct lsm303agr_common_data *cdata;
|
||||
|
||||
dev_info(&client->dev, "probe start.\n");
|
||||
|
||||
/* Alloc Common data structure */
|
||||
cdata = kzalloc(sizeof(struct lsm303agr_common_data), GFP_KERNEL);
|
||||
if (!cdata) {
|
||||
dev_err(&client->dev, "failed to allocate module data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cdata->sensor_num = LSM303AGR_MAX_SENSORS_NUM;
|
||||
cdata->dev = &client->dev;
|
||||
cdata->name = client->name;
|
||||
cdata->bus_type = BUS_I2C;
|
||||
cdata->tf = &lsm303agr_acc_i2c_tf;
|
||||
|
||||
i2c_set_clientdata(client, cdata);
|
||||
|
||||
mutex_init(&cdata->lock);
|
||||
|
||||
err = lsm303agr_acc_probe(cdata);
|
||||
if (err < 0) {
|
||||
kfree(cdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
|
||||
static void lsm303agr_acc_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
dev_info(cdata->dev, "driver removing\n");
|
||||
|
||||
lsm303agr_acc_remove(cdata);
|
||||
kfree(cdata);
|
||||
}
|
||||
#else
|
||||
static int lsm303agr_acc_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
dev_info(cdata->dev, "driver removing\n");
|
||||
|
||||
lsm303agr_acc_remove(cdata);
|
||||
kfree(cdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id lsm303agr_acc_i2c_id[] = {
|
||||
{ "lsm303agr_acc", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lsm303agr_acc_i2c_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id lsm303agr_acc_i2c_id_table[] = {
|
||||
{.compatible = "st,lsm303agr_acc", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lsm303agr_acc_i2c_id_table);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static struct i2c_driver lsm303agr_acc_i2c_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lsm303agr_acc",
|
||||
.pm = LSM303AGR_ACC_PM_OPS,
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = lsm303agr_acc_i2c_id_table,
|
||||
#endif /* CONFIG_OF */
|
||||
},
|
||||
.probe = lsm303agr_acc_i2c_probe,
|
||||
.remove = lsm303agr_acc_i2c_remove,
|
||||
.id_table = lsm303agr_acc_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(lsm303agr_acc_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("lsm303agr accelerometer i2c driver");
|
||||
MODULE_AUTHOR("Armando Visconti");
|
||||
MODULE_AUTHOR("Matteo Dameno");
|
||||
MODULE_AUTHOR("Denis Ciocca");
|
||||
MODULE_AUTHOR("STMicroelectronics");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* STMicroelectronics lsm303agr driver
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Giuseppe Barba <giuseppe.barba@st.com>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#ifndef __LSM303AGR_H__
|
||||
#define __LSM303AGR_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define LSM303AGR_MAX_SENSORS_NUM 1
|
||||
#define LSM303AGR_ACC_SENSOR 0 /* only this sensor */
|
||||
#define LSM303AGR_MAG_SENSOR 0 /* only this sensor */
|
||||
|
||||
struct lsm303agr_common_data;
|
||||
|
||||
/* specific bus I/O functions */
|
||||
struct lsm303agr_transfer_function {
|
||||
int (*write) (struct device *dev, u8 reg_addr, int len, u8 *data);
|
||||
int (*read) (struct device *dev, u8 reg_addr, int len, u8 *data);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_INPUT_LSM303AGR_SPI) || \
|
||||
defined(CONFIG_INPUT_LSM303AGR_SPI_MODULE)
|
||||
#define LSM303AGR_RX_MAX_LENGTH 500
|
||||
#define LSM303AGR_TX_MAX_LENGTH 500
|
||||
|
||||
struct lsm303agr_transfer_buffer {
|
||||
u8 rx_buf[LSM303AGR_RX_MAX_LENGTH];
|
||||
u8 tx_buf[LSM303AGR_TX_MAX_LENGTH] ____cacheline_aligned;
|
||||
};
|
||||
#endif /* CONFIG_INPUT_LSM303AGR_SPI */
|
||||
|
||||
/* Sensor data */
|
||||
struct lsm303agr_sensor_data {
|
||||
struct lsm303agr_common_data *cdata;
|
||||
const char* name;
|
||||
s64 timestamp;
|
||||
u8 enabled;
|
||||
u32 c_odr;
|
||||
u32 c_gain;
|
||||
u8 sindex;
|
||||
u8 sample_to_discard;
|
||||
u32 poll_interval;
|
||||
u32 min_interval;
|
||||
u8 fs_range;
|
||||
u32 sensitivity;
|
||||
u16 shift;
|
||||
u16 opmode;
|
||||
struct input_dev *input_dev;
|
||||
struct delayed_work input_work;
|
||||
u32 schedule_num; /* Number of time work_input routine is called */
|
||||
};
|
||||
|
||||
struct lsm303agr_common_data {
|
||||
const char *name;
|
||||
struct mutex lock;
|
||||
struct device *dev;
|
||||
int hw_initialized;
|
||||
atomic_t enabled;
|
||||
int on_before_suspend;
|
||||
u8 sensor_num;
|
||||
u16 bus_type;
|
||||
struct lsm303agr_sensor_data sensors[LSM303AGR_MAX_SENSORS_NUM];
|
||||
const struct lsm303agr_transfer_function *tf;
|
||||
#if defined(CONFIG_INPUT_LSM303AGR_SPI) || \
|
||||
defined(CONFIG_INPUT_LSM303AGR_SPI_MODULE)
|
||||
struct lsm303agr_transfer_buffer tb;
|
||||
#endif /* CONFIG_INPUT_LSM303AGR_SPI */
|
||||
};
|
||||
|
||||
/* Input events used by lsm303agr driver */
|
||||
#define INPUT_EVENT_TYPE EV_MSC
|
||||
#define INPUT_EVENT_X MSC_SERIAL
|
||||
#define INPUT_EVENT_Y MSC_PULSELED
|
||||
#define INPUT_EVENT_Z MSC_GESTURE
|
||||
#define INPUT_EVENT_TIME_MSB MSC_SCAN
|
||||
#define INPUT_EVENT_TIME_LSB MSC_MAX
|
||||
|
||||
static inline s64 lsm303agr_get_time_ns(void)
|
||||
{
|
||||
return ktime_to_ns(ktime_get_boottime());
|
||||
}
|
||||
|
||||
void lsm303agr_acc_remove(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_acc_probe(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_acc_enable(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_acc_disable(struct lsm303agr_common_data *cdata);
|
||||
|
||||
void lsm303agr_mag_remove(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_mag_probe(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_mag_enable(struct lsm303agr_common_data *cdata);
|
||||
int lsm303agr_mag_disable(struct lsm303agr_common_data *cdata);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __LSM303AGR_H__ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* STMicroelectronics lsm303agr_mag.c driver
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Giuseppe Barba <giuseppe.barba@st.com>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "lsm303agr_core.h"
|
||||
|
||||
#define LSM303AGR_MAG_DEV_NAME "lsm303agr_mag"
|
||||
|
||||
/* DEVICE REGISTERS */
|
||||
#define WHO_AM_I 0x4F
|
||||
#define CFG_REG_A 0x60
|
||||
#define AXISDATA_REG 0x68
|
||||
#define WHOAMI_LSM303AGR_MAG 0x40
|
||||
/* Device operating modes */
|
||||
#define MD_CONTINUOS_MODE 0x00
|
||||
#define MD_SINGLE_MODE 0x01
|
||||
#define MD_IDLE1_MODE 0x02
|
||||
#define MD_IDLE2_MODE 0x03
|
||||
#define LSM303AGR_MAG_MODE_MSK 0x03
|
||||
|
||||
/* Device ODRs */
|
||||
#define LSM303AGR_MAG_ODR10_HZ 0x00
|
||||
#define LSM303AGR_MAG_ODR20_HZ 0x04
|
||||
#define LSM303AGR_MAG_ODR50_HZ 0x08
|
||||
#define LSM303AGR_MAG_ODR100_HZ 0x0C
|
||||
#define LSM303AGR_MAG_ODR_MSK 0x0C
|
||||
|
||||
#define LSM303AGR_MAG_SENSITIVITY 1500 /* uGa/LSB */
|
||||
|
||||
/* ODR table */
|
||||
struct {
|
||||
u32 time_ms;
|
||||
u32 reg_val;
|
||||
} lsm303agr_mag_odr_table[] = {
|
||||
{ 10, LSM303AGR_MAG_ODR100_HZ }, /* ODR = 100Hz */
|
||||
{ 20, LSM303AGR_MAG_ODR50_HZ }, /* ODR = 50Hz */
|
||||
{ 50, LSM303AGR_MAG_ODR20_HZ }, /* ODR = 20Hz */
|
||||
{ 100, LSM303AGR_MAG_ODR10_HZ }, /* ODR = 10Hz */
|
||||
};
|
||||
|
||||
/* read and write with mask a given register */
|
||||
static int lsm303agr_mag_write_data_with_mask(struct lsm303agr_common_data *cdata,
|
||||
u8 reg_addr, u8 mask, u8 *data)
|
||||
{
|
||||
int err;
|
||||
u8 new_data, old_data = 0;
|
||||
|
||||
err = cdata->tf->read(cdata->dev, reg_addr, 1, &old_data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
new_data = ((old_data & (~mask)) | ((*data) & mask));
|
||||
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
dev_info(cdata->dev, "%s %02x o=%02x d=%02x n=%02x\n",
|
||||
LSM303AGR_MAG_DEV_NAME, reg_addr, old_data, *data, new_data);
|
||||
#endif
|
||||
|
||||
/* Save for caller usage the data that is about to be written */
|
||||
*data = new_data;
|
||||
|
||||
if (new_data == old_data)
|
||||
return 1;
|
||||
|
||||
return cdata->tf->write(cdata->dev, reg_addr, 1, &new_data);
|
||||
}
|
||||
|
||||
int lsm303agr_mag_input_init(struct lsm303agr_sensor_data *sdata,
|
||||
const char* description)
|
||||
{
|
||||
int err;
|
||||
|
||||
sdata->input_dev = input_allocate_device();
|
||||
if (!sdata->input_dev) {
|
||||
dev_err(sdata->cdata->dev, "input device allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sdata->input_dev->name = description;
|
||||
sdata->input_dev->id.bustype = sdata->cdata->bus_type;
|
||||
sdata->input_dev->dev.parent = sdata->cdata->dev;
|
||||
|
||||
input_set_drvdata(sdata->input_dev, sdata);
|
||||
|
||||
/* Set the input event characteristics of the probed sensor driver */
|
||||
set_bit(INPUT_EVENT_TYPE, sdata->input_dev->evbit );
|
||||
set_bit(INPUT_EVENT_TIME_MSB, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_TIME_LSB, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_X, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_Y, sdata->input_dev->mscbit);
|
||||
set_bit(INPUT_EVENT_Z, sdata->input_dev->mscbit);
|
||||
|
||||
err = input_register_device(sdata->input_dev);
|
||||
if (err) {
|
||||
dev_err(sdata->cdata->dev,
|
||||
"unable to register input device %s\n",
|
||||
sdata->input_dev->name);
|
||||
input_free_device(sdata->input_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if WHO_AM_I is correct */
|
||||
static int lsm303agr_mag_check_wai(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
int err;
|
||||
u8 wai;
|
||||
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
pr_info("%s: check WAI start\n", LSM303AGR_MAG_DEV_NAME);
|
||||
#endif
|
||||
|
||||
err = cdata->tf->read(cdata->dev, WHO_AM_I, 1, &wai);
|
||||
if (err < 0) {
|
||||
dev_warn(cdata->dev,
|
||||
"Error reading WHO_AM_I: is device available/working?\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (wai != WHOAMI_LSM303AGR_MAG) {
|
||||
dev_err(cdata->dev,
|
||||
"device unknown. Expected: 0x%02x," " Replies: 0x%02x\n",
|
||||
WHOAMI_LSM303AGR_MAG, wai);
|
||||
err = -1; /* choose the right coded error */
|
||||
goto error;
|
||||
}
|
||||
|
||||
cdata->hw_initialized = 1;
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
pr_info("%s: check WAI done\n", LSM303AGR_MAG_DEV_NAME);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cdata->hw_initialized = 0;
|
||||
dev_err(cdata->dev,
|
||||
"check WAI error 0x%02x,0x%02x: %d\n", WHO_AM_I, wai, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lsm303agr_mag_set_odr(struct lsm303agr_common_data *cdata, u8 odr)
|
||||
{
|
||||
u8 odr_reg;
|
||||
int err = -1, i;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
/**
|
||||
* Following, looks for the longest possible odr interval scrolling the
|
||||
* odr_table vector from the end (shortest interval) backward
|
||||
* (longest interval), to support the poll_interval requested
|
||||
* by the system. It must be the longest interval lower
|
||||
* than the poll interval
|
||||
*/
|
||||
for (i = ARRAY_SIZE(lsm303agr_mag_odr_table) - 1; i >= 0; i--) {
|
||||
if ((lsm303agr_mag_odr_table[i].time_ms <= odr) || (i == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
odr_reg = lsm303agr_mag_odr_table[i].reg_val;
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
sdata->poll_interval = sdata->c_odr = lsm303agr_mag_odr_table[i].time_ms;
|
||||
|
||||
/* If device is currently enabled, we need to write new
|
||||
* configuration out to it */
|
||||
if (atomic_read(&cdata->enabled)) {
|
||||
err = lsm303agr_mag_write_data_with_mask(cdata, CFG_REG_A,
|
||||
LSM303AGR_MAG_ODR_MSK,
|
||||
&odr_reg);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
dev_info(cdata->dev, "update odr to 0x%02x,0x%02x: %d\n",
|
||||
CFG_REG_A, odr_reg, err);
|
||||
#endif
|
||||
}
|
||||
|
||||
return lsm303agr_mag_odr_table[i].time_ms;
|
||||
|
||||
error:
|
||||
dev_err(cdata->dev, "set odr failed 0x%02x,0x%02x: %d\n",
|
||||
CFG_REG_A, odr_reg, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lsm303agr_mag_set_device_mode(struct lsm303agr_common_data *cdata,
|
||||
u8 mode)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = lsm303agr_mag_write_data_with_mask(cdata, CFG_REG_A,
|
||||
LSM303AGR_MAG_MODE_MSK,
|
||||
&mode);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
dev_info(cdata->dev, "update mode to 0x%02x,0x%02x: %d\n",
|
||||
CFG_REG_A, mode, err);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
dev_err(cdata->dev,
|
||||
"set continuos mode failed 0x%02x,0x%02x: %d\n",
|
||||
CFG_REG_A, mode, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set device in continuos mode */
|
||||
int lsm303agr_mag_enable(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
int err;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* Set the magnetometer in continuos mode */
|
||||
err = lsm303agr_mag_set_device_mode(cdata, MD_CONTINUOS_MODE);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "set_continuos failed: %d\n",
|
||||
err);
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
atomic_set(&cdata->enabled, 1);
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
if (lsm303agr_mag_set_odr(cdata, sdata->c_odr) < 0) {
|
||||
mutex_unlock(&cdata->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Start scheduling input */
|
||||
schedule_delayed_work(&sdata->input_work,
|
||||
msecs_to_jiffies(sdata->poll_interval));
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_mag_enable);
|
||||
|
||||
/* Set device in idle mode */
|
||||
int lsm303agr_mag_disable(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
if (atomic_cmpxchg(&cdata->enabled, 1, 0)) {
|
||||
int err;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
cancel_delayed_work_sync(&sdata->input_work);
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* Set the magnetometer in idle mode */
|
||||
err = lsm303agr_mag_set_device_mode(cdata, MD_IDLE2_MODE);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "set_idle failed: %d\n",
|
||||
err);
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
mutex_unlock(&cdata->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_mag_disable);
|
||||
|
||||
static void lsm303agr_mag_report_event(struct lsm303agr_common_data *cdata,
|
||||
int *xyz, s64 timestamp)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_X, xyz[0]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_Y, xyz[1]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_Z, xyz[2]);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_TIME_MSB,
|
||||
timestamp >> 32);
|
||||
input_event(sdata->input_dev, INPUT_EVENT_TYPE, INPUT_EVENT_TIME_LSB,
|
||||
timestamp & 0xffffffff);
|
||||
input_sync(sdata->input_dev);
|
||||
}
|
||||
|
||||
static int lsm303agr_mag_get_data(struct lsm303agr_common_data *cdata,
|
||||
int *xyz)
|
||||
{
|
||||
int err;
|
||||
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
|
||||
u8 mag_data[6];
|
||||
|
||||
err = cdata->tf->read(cdata->dev, AXISDATA_REG, 6, mag_data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Transform LSBs into ug */
|
||||
xyz[0] = (s32)((s16)(mag_data[0] | (mag_data[1] << 8)));
|
||||
xyz[0] *= LSM303AGR_MAG_SENSITIVITY;
|
||||
xyz[1] = (s32)((s16)(mag_data[2] | (mag_data[3] << 8)));
|
||||
xyz[1] *= LSM303AGR_MAG_SENSITIVITY;
|
||||
xyz[2] = (s32)((s16)(mag_data[4] | (mag_data[5] << 8)));
|
||||
xyz[2] *= LSM303AGR_MAG_SENSITIVITY;
|
||||
|
||||
#ifdef LSM303AGR_MAG_DEBUG
|
||||
dev_info(cdata->dev, "%s read x=%d, y=%d, z=%d\n",
|
||||
LSM303AGR_MAG_DEV_NAME, xyz[0], xyz[1], xyz[2]);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lsm303agr_mag_input_work_func(struct work_struct *work)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
int err, xyz[3] = {};
|
||||
|
||||
sdata = container_of((struct delayed_work *)work,
|
||||
struct lsm303agr_sensor_data, input_work);
|
||||
cdata = sdata->cdata;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
sdata->schedule_num++;
|
||||
err = lsm303agr_mag_get_data(cdata, xyz);
|
||||
if (err < 0)
|
||||
dev_err(cdata->dev, "get_mag_data failed\n");
|
||||
else
|
||||
lsm303agr_mag_report_event(cdata, xyz,
|
||||
lsm303agr_get_time_ns());
|
||||
|
||||
schedule_delayed_work(&sdata->input_work,
|
||||
msecs_to_jiffies(sdata->poll_interval));
|
||||
mutex_unlock(&cdata->lock);
|
||||
}
|
||||
|
||||
static void lsm303agr_mag_input_cleanup(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
input_unregister_device(sdata->input_dev);
|
||||
input_free_device(sdata->input_dev);
|
||||
}
|
||||
|
||||
/* SYSFS: set val to polling_ms ATTR */
|
||||
static ssize_t attr_get_polling_rate_mag(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u32 val = 0;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
|
||||
/* read from platform data */
|
||||
mutex_lock(&cdata->lock);
|
||||
val = sdata->poll_interval;
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t attr_set_polling_rate_mag(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
if (kstrtoul(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* set ODR */
|
||||
val = lsm303agr_mag_set_odr(cdata, val);
|
||||
if (val < 0) {
|
||||
mutex_unlock(&cdata->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write to platform data */
|
||||
cdata->sensors[LSM303AGR_MAG_SENSOR].poll_interval = val;
|
||||
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* SYSFS: set val to enable_device ATTR */
|
||||
static ssize_t attr_get_enable_mag(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
int val = atomic_read(&cdata->enabled);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
/* SYSFS: get val from enable_device ATTR */
|
||||
static ssize_t attr_set_enable_mag(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long val;
|
||||
struct lsm303agr_common_data *cdata = dev_get_drvdata(dev);
|
||||
|
||||
if (kstrtoul(buf, 10, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
lsm303agr_mag_enable(cdata);
|
||||
else
|
||||
lsm303agr_mag_disable(cdata);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct device_attribute lsm303agr_mag_attributes[] = {
|
||||
__ATTR(pollrate_ms, 0664, attr_get_polling_rate_mag,
|
||||
attr_set_polling_rate_mag),
|
||||
__ATTR(enable_device, 0664, attr_get_enable_mag, attr_set_enable_mag),
|
||||
};
|
||||
|
||||
static int create_sysfs_interfaces(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lsm303agr_mag_attributes); i++)
|
||||
if (device_create_file(dev, lsm303agr_mag_attributes + i))
|
||||
goto error;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (; i >= 0; i--)
|
||||
device_remove_file(dev, lsm303agr_mag_attributes + i);
|
||||
|
||||
dev_err(dev, "%s:Unable to create interface\n", __func__);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int remove_sysfs_interfaces(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lsm303agr_mag_attributes); i++)
|
||||
device_remove_file(dev, lsm303agr_mag_attributes + i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsm303agr_mag_probe(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
int err;
|
||||
struct lsm303agr_sensor_data *sdata;
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* init sensor data structure */
|
||||
sdata = &cdata->sensors[LSM303AGR_MAG_SENSOR];
|
||||
sdata->cdata = cdata;
|
||||
|
||||
/* Check WHO_AM_I */
|
||||
err = lsm303agr_mag_check_wai(cdata);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "check WAI failed\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set device ODR to 100ms (10Hz) */
|
||||
err = lsm303agr_mag_set_odr(cdata, 100);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "Set ODR On failed\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Disable Magnetometer to save power */
|
||||
mutex_unlock(&cdata->lock);
|
||||
err = lsm303agr_mag_disable(cdata);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "Power On failed\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
mutex_lock(&cdata->lock);
|
||||
/* Init the input framework */
|
||||
err = lsm303agr_mag_input_init(sdata, LSM303AGR_MAG_DEV_NAME);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev, "input init failed\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
INIT_DELAYED_WORK(&sdata->input_work, lsm303agr_mag_input_work_func);
|
||||
|
||||
/* Create SYSFS interface */
|
||||
err = create_sysfs_interfaces(cdata->dev);
|
||||
if (err < 0) {
|
||||
dev_err(cdata->dev,
|
||||
"device LSM303AGR_MAG_DEV_NAME sysfs register failed\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_info(cdata->dev, "%s: probed\n", LSM303AGR_MAG_DEV_NAME);
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_mag_probe);
|
||||
|
||||
void lsm303agr_mag_remove(struct lsm303agr_common_data *cdata)
|
||||
{
|
||||
lsm303agr_mag_disable(cdata);
|
||||
lsm303agr_mag_input_cleanup(cdata);
|
||||
remove_sysfs_interfaces(cdata->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(lsm303agr_mag_remove);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* STMicroelectronics lsm303agr_mag_i2c.c driver
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Giuseppe Barba <giuseppe.barba@st.com>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "lsm303agr_core.h"
|
||||
|
||||
#define I2C_AUTO_INCREMENT 0x80
|
||||
|
||||
/* XXX: caller must hold cdata->lock */
|
||||
static int lsm303agr_mag_i2c_read(struct device *dev, u8 reg_addr, int len,
|
||||
u8 *data)
|
||||
{
|
||||
struct i2c_msg msg[2];
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (len > 1)
|
||||
reg_addr |= I2C_AUTO_INCREMENT;
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = client->flags;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = ®_addr;
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = client->flags | I2C_M_RD;
|
||||
msg[1].len = len;
|
||||
msg[1].buf = data;
|
||||
|
||||
return i2c_transfer(client->adapter, msg, 2);
|
||||
}
|
||||
|
||||
/* XXX: caller must hold cdata->lock */
|
||||
static int lsm303agr_mag_i2c_write(struct device *dev, u8 reg_addr, int len,
|
||||
u8 *data)
|
||||
{
|
||||
u8 send[len + 1];
|
||||
struct i2c_msg msg;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (len > 1)
|
||||
reg_addr |= I2C_AUTO_INCREMENT;
|
||||
|
||||
send[0] = reg_addr;
|
||||
memcpy(&send[1], data, len * sizeof(u8));
|
||||
len++;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = client->flags;
|
||||
msg.len = len;
|
||||
msg.buf = send;
|
||||
|
||||
return i2c_transfer(client->adapter, &msg, 1);
|
||||
}
|
||||
|
||||
/* I2C IO routines */
|
||||
static const struct lsm303agr_transfer_function lsm303agr_mag_i2c_tf = {
|
||||
.write = lsm303agr_mag_i2c_write,
|
||||
.read = lsm303agr_mag_i2c_read,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int lsm303agr_mag_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
if (cdata->on_before_suspend)
|
||||
return lsm303agr_mag_enable(cdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsm303agr_mag_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
cdata->on_before_suspend = atomic_read(&cdata->enabled);
|
||||
return lsm303agr_mag_disable(cdata);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(lsm303agr_mag_pm_ops,
|
||||
lsm303agr_mag_suspend,
|
||||
lsm303agr_mag_resume);
|
||||
|
||||
#define LSM303AGR_MAG_PM_OPS (&lsm303agr_mag_pm_ops)
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
#define LSM303AGR_MAG_PM_OPS NULL
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static int lsm303agr_mag_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int err;
|
||||
struct lsm303agr_common_data *cdata;
|
||||
|
||||
dev_info(&client->dev, "probe start.\n");
|
||||
|
||||
/* Alloc Common data structure */
|
||||
cdata = kzalloc(sizeof(struct lsm303agr_common_data), GFP_KERNEL);
|
||||
if (cdata == NULL) {
|
||||
dev_err(&client->dev,
|
||||
"failed to allocate memory for module data\n");
|
||||
mutex_unlock(&cdata->lock);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cdata->sensor_num = LSM303AGR_MAX_SENSORS_NUM;
|
||||
cdata->dev = &client->dev;
|
||||
cdata->name = client->name;
|
||||
cdata->bus_type = BUS_I2C;
|
||||
cdata->tf = &lsm303agr_mag_i2c_tf;
|
||||
|
||||
i2c_set_clientdata(client, cdata);
|
||||
|
||||
mutex_init(&cdata->lock);
|
||||
|
||||
err = lsm303agr_mag_probe(cdata);
|
||||
if (err < 0) {
|
||||
kfree(cdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
|
||||
static void lsm303agr_mag_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
dev_info(cdata->dev, "driver removing\n");
|
||||
|
||||
lsm303agr_mag_remove(cdata);
|
||||
kfree(cdata);
|
||||
}
|
||||
#else
|
||||
static int lsm303agr_mag_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lsm303agr_common_data *cdata = i2c_get_clientdata(client);
|
||||
|
||||
dev_info(cdata->dev, "driver removing\n");
|
||||
|
||||
lsm303agr_mag_remove(cdata);
|
||||
kfree(cdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id lsm303agr_mag_i2c_id[] = {
|
||||
{ "lsm303agr_mag", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lsm303agr_mag_i2c_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id lsm303agr_mag_i2c_id_table[] = {
|
||||
{.compatible = "st,lsm303agr_mag", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lsm303agr_mag_i2c_id_table);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static struct i2c_driver lsm303agr_mag_i2c_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lsm303agr_mag",
|
||||
.pm = LSM303AGR_MAG_PM_OPS,
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = lsm303agr_mag_i2c_id_table,
|
||||
#endif /* CONFIG_OF */
|
||||
},
|
||||
.probe = lsm303agr_mag_i2c_probe,
|
||||
.remove = lsm303agr_mag_i2c_remove,
|
||||
.id_table = lsm303agr_mag_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(lsm303agr_mag_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("lsm303agr magnetometer i2c driver");
|
||||
MODULE_AUTHOR("Armando Visconti");
|
||||
MODULE_AUTHOR("Matteo Dameno");
|
||||
MODULE_AUTHOR("Denis Ciocca");
|
||||
MODULE_AUTHOR("STMicroelectronics");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
228
feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtl8221d.c
Normal file
228
feeds/qca-wifi-7/ipq53xx/files-6.1/drivers/net/phy/rtl8221d.c
Normal file
@@ -0,0 +1,228 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for Rtl PHY
|
||||
*
|
||||
* Author: Huang Yunxiang <huangyunxiang@cigtech.com>
|
||||
*
|
||||
* Copyright 2024 cig, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#define PHY_ID_RTL8221D 0x001CC841
|
||||
#define BIT_0 0x0001
|
||||
#define BIT_1 0x0002
|
||||
#define BIT_2 0x0004
|
||||
#define BIT_3 0x0008
|
||||
#define BIT_4 0x0010
|
||||
#define BIT_5 0x0020
|
||||
#define BIT_6 0x0040
|
||||
#define BIT_7 0x0080
|
||||
#define BIT_8 0x0100
|
||||
#define BIT_9 0x0200
|
||||
#define BIT_10 0x0400
|
||||
#define BIT_11 0x0800
|
||||
#define BIT_12 0x1000
|
||||
#define BIT_13 0x2000
|
||||
#define BIT_14 0x4000
|
||||
#define BIT_15 0x8000
|
||||
|
||||
|
||||
static int rtl8221d_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static u32 Rtl8226b_is_link(struct phy_device *phydev)
|
||||
{
|
||||
int phydata = 0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
// must read twice
|
||||
for(i=0;i<2;i++)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA402);
|
||||
}
|
||||
|
||||
phydev->link = (phydata & BIT_2) ? (1) : (0);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int rtl8221d_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int phydata, speed_grp, speed;
|
||||
|
||||
Rtl8226b_is_link(phydev);
|
||||
if (phydev->link)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
|
||||
speed_grp = (phydata & (BIT_9 | BIT_10)) >> 9;
|
||||
speed = (phydata & (BIT_4 | BIT_5)) >> 4;
|
||||
switch(speed_grp)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
switch(speed)
|
||||
{
|
||||
case 1:
|
||||
phydev->speed = SPEED_100;
|
||||
break;
|
||||
case 2:
|
||||
phydev->speed = SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
switch(speed)
|
||||
{
|
||||
case 1:
|
||||
phydev->speed = SPEED_2500;
|
||||
break;
|
||||
case 3:
|
||||
phydev->speed = SPEED_1000; // 2.5G lite
|
||||
break;
|
||||
default:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phydev->speed = SPEED_10;
|
||||
}
|
||||
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
|
||||
phydev->duplex = (phydata & BIT_3) ? (DUPLEX_FULL) : (DUPLEX_HALF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8221d_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
int phydata;
|
||||
u16 timeoutms = 100;
|
||||
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
|
||||
if (err < 0)
|
||||
return err;
|
||||
while(--timeoutms)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND1, 0x7587);
|
||||
if((phydata & 0x01) == 0)
|
||||
break;
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND1, 0x75F3);
|
||||
phydata &= ~BIT_0;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75F3, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND1, 0x697A);
|
||||
phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5));
|
||||
phydata |= 2;
|
||||
phydata |=0x8000;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x697A, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND1, 0x697A);
|
||||
|
||||
Rtl8226b_is_link(phydev);
|
||||
if (phydev->link)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 0x0);
|
||||
phydata |= BIT_15;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, 0x0, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
while(--timeoutms)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 0x0);
|
||||
if (!(phydata & BIT_15))
|
||||
break;
|
||||
mdelay(10);
|
||||
}
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, 0x0, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa400);
|
||||
phydata |= BIT_14;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa400, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
while(--timeoutms)
|
||||
{
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434);
|
||||
if (phydata & BIT_2)
|
||||
break;
|
||||
mdelay(10);
|
||||
}
|
||||
phydata = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa400);
|
||||
phydata &= ~BIT_14;
|
||||
err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa400, phydata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8221d_probe(struct phy_device *phydev)
|
||||
{
|
||||
printk("rtl8221d probe");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct phy_driver aqr_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_RTL8221D),
|
||||
.name = "Rtl 8221D",
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.probe = rtl8221d_probe,
|
||||
.config_init = rtl8221d_config_init,
|
||||
.config_aneg = rtl8221d_config_aneg,
|
||||
.read_status = rtl8221d_read_status,
|
||||
},
|
||||
};
|
||||
|
||||
module_phy_driver(aqr_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused rtl_tbl[] = {
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_RTL8221D) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(mdio, rtl_tbl);
|
||||
|
||||
MODULE_DESCRIPTION("rtl8221d PHY driver");
|
||||
MODULE_AUTHOR("haungyunxiang huangyunxiang@cigtech.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -79,6 +79,20 @@ define Device/sonicfi_rap750e_h
|
||||
endef
|
||||
TARGET_DEVICES += sonicfi_rap750e_h
|
||||
|
||||
define Device/sonicfi_rap750e_s
|
||||
DEVICE_TITLE := SONICFI RAP750E-S
|
||||
DEVICE_DTS := ipq5332-sonicfi-rap750e-s
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_DTS_CONFIG := config@mi01.3-c2
|
||||
SUPPORTED_DEVICES := sonicfi,rap750e-s
|
||||
IMAGES := sysupgrade.tar nand-factory.bin nand-factory.ubi
|
||||
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
|
||||
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
|
||||
IMAGE/nand-factory.ubi := append-ubi
|
||||
DEVICE_PACKAGES := ath12k-wifi-sonicfi-rap750e-s ath12k-firmware-ipq5332-peb -ath12k-firmware-qcn92xx
|
||||
endef
|
||||
TARGET_DEVICES += sonicfi_rap750e_s
|
||||
|
||||
define Device/sonicfi_rap750w_311a
|
||||
DEVICE_TITLE := SONICFI RAP750W-311A
|
||||
DEVICE_DTS := ipq5332-sonicfi-rap750w-311a
|
||||
@@ -119,3 +133,30 @@ define Device/cig_wf189h
|
||||
DEVICE_PACKAGES := ath12k-wifi-cig-wf189h ath12k-firmware-ipq5332-peb-peb
|
||||
endef
|
||||
TARGET_DEVICES += cig_wf189h
|
||||
|
||||
define Device/zyxel_nwa130be
|
||||
DEVICE_TITLE := Zyxel NWA130BE
|
||||
DEVICE_DTS := ipq5332-zyxel-nwa130be
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_DTS_CONFIG := config@mi01.6
|
||||
IMAGES := sysupgrade.tar nand-factory.bin nand-factory.ubi
|
||||
BLOCKSIZE := 256k
|
||||
PAGESIZE := 4096
|
||||
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
|
||||
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
|
||||
IMAGE/nand-factory.ubi := append-ubi
|
||||
DEVICE_PACKAGES := ath12k-wifi-zyxel-nwa130be ath12k-firmware-qcn92xx ath12k-firmware-ipq5332
|
||||
endef
|
||||
TARGET_DEVICES += zyxel_nwa130be
|
||||
|
||||
define Device/cig_wf672
|
||||
DEVICE_TITLE := CIG WF672
|
||||
DEVICE_DTS := ipq5332-cig-wf672
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_DTS_CONFIG := config@mi01.6
|
||||
IMAGES := sysupgrade.tar mmc-factory.bin
|
||||
IMAGE/mmc-factory.bin := append-ubi | qsdk-ipq-factory-mmc
|
||||
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
|
||||
DEVICE_PACKAGES := ath12k-wifi-cig-wf672 ath12k-firmware-ipq5332 ath12k-firmware-qcn92xx
|
||||
endef
|
||||
TARGET_DEVICES += cig_wf672
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
--- a/drivers/input/misc/Kconfig 2025-04-22 14:35:28.228629072 +0800
|
||||
+++ b/drivers/input/misc/Kconfig 2025-04-22 14:42:29.630935581 +0800
|
||||
@@ -929,4 +929,5 @@
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stpmic1_onkey.
|
||||
|
||||
+source "drivers/input/misc/lsm303agr/Kconfig"
|
||||
endif
|
||||
--- a/drivers/input/misc/Makefile 2025-04-22 14:35:28.228629072 +0800
|
||||
+++ b/drivers/input/misc/Makefile 2025-04-22 14:41:23.840267623 +0800
|
||||
@@ -89,3 +89,4 @@
|
||||
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
|
||||
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
|
||||
obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o
|
||||
+obj-$(CONFIG_INPUT_LSM303AGR) += lsm303agr/
|
||||
--- a/drivers/net/phy/Kconfig 2025-04-22 14:48:04.858191804 +0800
|
||||
+++ b/drivers/net/phy/Kconfig 2025-04-22 10:17:06.822705335 +0800
|
||||
@@ -99,6 +99,9 @@
|
||||
tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
|
||||
select SWCONFIG
|
||||
|
||||
+config RTL8221D_PHY
|
||||
+ tristate "Driver for Realtek RTL8221D phy"
|
||||
+
|
||||
config RTL8306_PHY
|
||||
tristate "Driver for Realtek RTL8306S switches"
|
||||
select SWCONFIG
|
||||
--- a/drivers/net/phy/Makefile 2025-04-22 14:48:18.254372527 +0800
|
||||
+++ b/drivers/net/phy/Makefile 2025-04-22 10:17:10.546732447 +0800
|
||||
@@ -32,6 +32,7 @@
|
||||
obj-$(CONFIG_SWCONFIG_B53) += b53/
|
||||
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
|
||||
obj-$(CONFIG_PSB6970_PHY) += psb6970.o
|
||||
+obj-$(CONFIG_RTL8221D_PHY) += rtl8221d.o
|
||||
obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
|
||||
obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
|
||||
obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
|
||||
--- a/drivers/iio/pressure/Kconfig 2025-05-13 15:16:05.019840003 +0800
|
||||
+++ b/drivers/iio/pressure/Kconfig 2025-05-13 15:17:45.032040654 +0800
|
||||
@@ -266,4 +266,11 @@
|
||||
tristate
|
||||
select REGMAP_SPI
|
||||
|
||||
+config ILPS22QS
|
||||
+ tristate "ILPS22QS pressure support"
|
||||
+ help
|
||||
+ Say Y to enable support ILPS22QS
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called ILPS22QS.
|
||||
endmenu
|
||||
|
||||
--- a/drivers/iio/pressure/Makefile 2025-05-13 15:17:58.049195788 +0800
|
||||
+++ b/drivers/iio/pressure/Makefile 2025-05-13 15:19:07.205016058 +0800
|
||||
@@ -31,6 +31,8 @@
|
||||
obj-$(CONFIG_ZPA2326) += zpa2326.o
|
||||
obj-$(CONFIG_ZPA2326_I2C) += zpa2326_i2c.o
|
||||
obj-$(CONFIG_ZPA2326_SPI) += zpa2326_spi.o
|
||||
+obj-$(CONFIG_ILPS22QS) += st_ilps22qs.o
|
||||
+st_ilps22qs-objs := st_ilps22qs_i2c.o st_ilps22qs_core.o
|
||||
|
||||
obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
|
||||
obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
|
||||
@@ -397,7 +397,7 @@ export function info(name) {
|
||||
mode: data.mode,
|
||||
channel: format_channel(data.wiphy_freq),
|
||||
freq: format_frequency(data.wiphy_freq),
|
||||
htmode: data.radio.htmode,
|
||||
htmode: data?.radio?.htmode,
|
||||
center_freq1: format_channel(data.center_freq1) || 'unknown',
|
||||
center_freq2: format_channel(data.center_freq2) || 'unknown',
|
||||
txpower: data.wiphy_tx_power_level / 100,
|
||||
|
||||
@@ -262,6 +262,11 @@ define KernelPackage/mt7601u
|
||||
AUTOLOAD:=$(call AutoProbe,mt7601u)
|
||||
endef
|
||||
|
||||
ifdef CONFIG_TARGET_PROFILE
|
||||
TARGET_PROFILE=$(subst ",,$(CONFIG_TARGET_PROFILE))
|
||||
PATCH_PROFILE_NAME=patches-$(subst DEVICE_,,$(TARGET_PROFILE))
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
|
||||
config-y += \
|
||||
CFG80211_DEBUGFS \
|
||||
@@ -362,6 +367,7 @@ define Build/Patch
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(EXTERNAL_PATCH_DIR)/ath12k,ath12k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(EXTERNAL_PATCH_DIR)/pending,pending/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_TIP_DIR)/pending,pending/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_PROFILE_NAME)/ath12k,ath12k/)
|
||||
$(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used)
|
||||
endef
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
From 1a46aa106a50a06bfa4b669d87a8143c3d59f2f4 Mon Sep 17 00:00:00 2001
|
||||
From: YenLin Pan <yenlin.pan@zyxel.com.tw>
|
||||
Date: Wed, 14 May 2025 14:14:22 +0800
|
||||
Subject: [PATCH] thermal: thermal setting
|
||||
|
||||
lv0 -100 -hi0 105 -off0 0
|
||||
lv1 95 -hi1 110 -off1 75
|
||||
lv2 100 -hi2 115 -off2 98
|
||||
lv3 105 -hi3 120 -off3 100
|
||||
|
||||
Signed-off-by: YenLin Pan <YenLin.Pan@zyxel.com.tw>
|
||||
---
|
||||
drivers/net/wireless/ath/ath12k/thermal.h | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/ath/ath12k/thermal.h b/drivers/net/wireless/ath/ath12k/thermal.h
|
||||
index 5c91906..a493cd5 100644
|
||||
--- a/drivers/net/wireless/ath/ath12k/thermal.h
|
||||
+++ b/drivers/net/wireless/ath/ath12k/thermal.h
|
||||
@@ -13,28 +13,28 @@
|
||||
|
||||
/* Below temperatures are in celsius */
|
||||
#define ATH12K_THERMAL_LVL0_TEMP_LOW_MARK -100
|
||||
-#define ATH12K_THERMAL_LVL0_TEMP_HIGH_MARK 100
|
||||
+#define ATH12K_THERMAL_LVL0_TEMP_HIGH_MARK 105
|
||||
#define ATH12K_THERMAL_LVL1_TEMP_LOW_MARK 95
|
||||
-#define ATH12K_THERMAL_LVL1_TEMP_HIGH_MARK 105
|
||||
+#define ATH12K_THERMAL_LVL1_TEMP_HIGH_MARK 110
|
||||
#define ATH12K_THERMAL_LVL2_TEMP_LOW_MARK 100
|
||||
-#define ATH12K_THERMAL_LVL2_TEMP_HIGH_MARK 110
|
||||
+#define ATH12K_THERMAL_LVL2_TEMP_HIGH_MARK 115
|
||||
#define ATH12K_THERMAL_LVL3_TEMP_LOW_MARK 105
|
||||
#define ATH12K_THERMAL_LVL3_TEMP_HIGH_MARK 120
|
||||
|
||||
#define ATH12K_THERMAL_LVL0_V2_TEMP_LOW_MARK -100
|
||||
-#define ATH12K_THERMAL_LVL0_V2_TEMP_HIGH_MARK 95
|
||||
+#define ATH12K_THERMAL_LVL0_V2_TEMP_HIGH_MARK 105
|
||||
#define ATH12K_THERMAL_LVL1_V2_TEMP_LOW_MARK 90
|
||||
-#define ATH12K_THERMAL_LVL1_V2_TEMP_HIGH_MARK 100
|
||||
+#define ATH12K_THERMAL_LVL1_V2_TEMP_HIGH_MARK 110
|
||||
#define ATH12K_THERMAL_LVL2_V2_TEMP_LOW_MARK 95
|
||||
#define ATH12K_THERMAL_LVL2_V2_TEMP_HIGH_MARK 105
|
||||
#define ATH12K_THERMAL_LVL3_V2_TEMP_LOW_MARK 100
|
||||
-#define ATH12K_THERMAL_LVL3_V2_TEMP_HIGH_MARK 110
|
||||
+#define ATH12K_THERMAL_LVL3_V2_TEMP_HIGH_MARK 115
|
||||
#define ATH12K_THERMAL_LVL4_V2_TEMP_LOW_MARK 105
|
||||
#define ATH12K_THERMAL_LVL4_V2_TEMP_HIGH_MARK 120
|
||||
|
||||
#define ATH12K_THERMAL_LVL0_DUTY_CYCLE 0
|
||||
-#define ATH12K_THERMAL_LVL1_DUTY_CYCLE 50
|
||||
-#define ATH12K_THERMAL_LVL2_DUTY_CYCLE 90
|
||||
+#define ATH12K_THERMAL_LVL1_DUTY_CYCLE 75
|
||||
+#define ATH12K_THERMAL_LVL2_DUTY_CYCLE 98
|
||||
#define ATH12K_THERMAL_LVL3_DUTY_CYCLE 100
|
||||
|
||||
#define ATH12K_THERMAL_LVL0_V2_DUTY_CYCLE ATH12K_THERMAL_LVL0_DUTY_CYCLE
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -702,3 +702,44 @@ define KernelPackage/llcc_perfmon/description
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,llcc_perfmon))
|
||||
|
||||
define KernelPackage/input-lsm303agr
|
||||
SUBMENU:=$(OTHER_MENU)
|
||||
TITLE:=LSM303AGR Driver
|
||||
DEPENDS+=@TARGET_ipq53xx
|
||||
KCONFIG:=CONFIG_INPUT_LSM303AGR=y
|
||||
endef
|
||||
|
||||
define KernelPackage/input-lsm303agr/description
|
||||
lsm303agr driver support
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,input-lsm303agr))
|
||||
|
||||
define KernelPackage/rtl8221d-phy
|
||||
SUBMENU:=$(OTHER_MENU)
|
||||
TITLE:=RTL8221d PHY Driver
|
||||
DEPENDS+=@TARGET_ipq53xx
|
||||
KCONFIG:=CONFIG_RTL8221D_PHY=y
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8221d-phy/description
|
||||
RTL8221d PHY driver support
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,rtl8221d-phy))
|
||||
|
||||
define KernelPackage/iio-ilps22qs
|
||||
SUBMENU:=$(IIO_MENU)
|
||||
TITLE:= pressure sensors ilps22qs Driver
|
||||
DEPENDS+=@TARGET_ipq53xx +kmod-iio-core +kmod-industrialio-triggered-buffer
|
||||
KCONFIG:=CONFIG_ILPS22QS
|
||||
FILES:=$(LINUX_DIR)/drivers/iio/pressure/st_ilps22qs.ko
|
||||
AUTOLOAD:=$(call AutoLoad,80,st_ilps22qs)
|
||||
endef
|
||||
|
||||
define KernelPackage/iio-ilps22qs/description
|
||||
pressure sensors ilps22qs driver support
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,iio-ilps22qs))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user