1
0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-10-18 21:48:23 +02:00

brcm2708: add more patches for linux 4.9

Also removes unneeded wireless patches

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
This commit is contained in:
Álvaro Fernández Rojas 2017-02-08 09:10:39 +01:00
parent 7ef713c9c4
commit ba9dbc3dd5
14 changed files with 1662 additions and 173463 deletions

@ -304,6 +304,8 @@ CONFIG_RASPBERRYPI_POWER=y
CONFIG_RATIONAL=y
CONFIG_RAW_DRIVER=y
# CONFIG_RCU_STALL_COMMON is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_SCHED_HRTICK=y
# CONFIG_SCHED_INFO is not set

@ -334,6 +334,8 @@ CONFIG_RAW_DRIVER=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y

@ -74,8 +74,6 @@ CONFIG_BCM2835_MBOX=y
CONFIG_BCM2835_WDT=y
# CONFIG_BCM_PDC_MBOX is not set
# CONFIG_BCM_VCIO is not set
# CONFIG_BCM_VC_CMA is not set
# CONFIG_BCM_VC_SM is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
@ -355,6 +353,8 @@ CONFIG_RAW_DRIVER=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y

@ -1,1125 +0,0 @@
From 911b758ea2b7741fdc71ab47685d55d0a6452c72 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 23 Mar 2016 17:20:58 +0000
Subject: [PATCH] net: Fix rtl8192cu build errors on other platforms
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
suppress spurious messages
Add #if for 3.14 kernel change (#87)
Fixes compiling after changes in https://github.com/torvalds/linux/commit/f663dd9aaf9ed124f25f0f8452edf238f087ad50 and https://github.com/torvalds/linux/commit/99932d4fc03a13bb3e94938fe25458fabc8f2fc3
Fixes #86
Set dev_type to wlan
Fixes #23
Tentatively added support for more 8188CUS based devices.
Add support for more 8188CUS and 8192CUS devices
Add ProductId for the Netgear N150 - WNA1000M
Fixes CONFIG_CONCURRENT_MODE CONFIG_MULTI_VIR_IFACES
Fixes compatibility with 3.13
Enables warning in the compiler and fixes some issues, reference => https://github.com/diederikdehaas/rtl8812AU
Starts device in station mode instead of monitor, fixes NetworkManager issues
Enable cfg80211 support
Fix cfg80211 for kernel >= 4.7
Fixes rtl8192cu for kernel >= 4.8
---
drivers/net/wireless/realtek/rtl8192cu/Makefile | 20 ++-
.../net/wireless/realtek/rtl8192cu/core/rtw_ap.c | 7 +-
.../realtek/rtl8192cu/core/rtw_ieee80211.c | 3 +-
.../realtek/rtl8192cu/core/rtw_ioctl_set.c | 5 +-
.../wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c | 8 +-
.../net/wireless/realtek/rtl8192cu/core/rtw_p2p.c | 6 +-
.../net/wireless/realtek/rtl8192cu/core/rtw_recv.c | 7 +-
.../wireless/realtek/rtl8192cu/core/rtw_sta_mgt.c | 4 +-
.../realtek/rtl8192cu/core/rtw_wlan_util.c | 2 +-
.../net/wireless/realtek/rtl8192cu/core/rtw_xmit.c | 2 +-
.../rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c | 4 +-
.../wireless/realtek/rtl8192cu/include/autoconf.h | 9 +-
.../realtek/rtl8192cu/include/ioctl_cfg80211.h | 9 +-
.../realtek/rtl8192cu/include/osdep_service.h | 4 +-
.../wireless/realtek/rtl8192cu/include/rtw_debug.h | 6 +-
.../realtek/rtl8192cu/include/rtw_ioctl_set.h | 5 +-
.../wireless/realtek/rtl8192cu/include/sta_info.h | 4 +-
.../net/wireless/realtek/rtl8192cu/include/wifi.h | 2 +-
.../rtl8192cu/os_dep/linux/ioctl_cfg80211.c | 176 ++++++++++++++-------
.../realtek/rtl8192cu/os_dep/linux/ioctl_linux.c | 3 +-
.../realtek/rtl8192cu/os_dep/linux/os_intfs.c | 18 ++-
.../realtek/rtl8192cu/os_dep/linux/recv_linux.c | 2 +-
.../realtek/rtl8192cu/os_dep/linux/rtw_android.c | 6 -
.../realtek/rtl8192cu/os_dep/linux/usb_intf.c | 9 +-
.../realtek/rtl8192cu/os_dep/osdep_service.c | 4 +-
25 files changed, 214 insertions(+), 111 deletions(-)
--- a/drivers/net/wireless/realtek/rtl8192cu/Makefile
+++ b/drivers/net/wireless/realtek/rtl8192cu/Makefile
@@ -1,12 +1,20 @@
EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
EXTRA_CFLAGS += -O1
#EXTRA_CFLAGS += -O3
-#EXTRA_CFLAGS += -Wall
-#EXTRA_CFLAGS += -Wextra
+EXTRA_CFLAGS += -Wall
+EXTRA_CFLAGS += -Wextra
#EXTRA_CFLAGS += -Werror
#EXTRA_CFLAGS += -pedantic
#EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes
+# The "$(call cc-option,-Wxxx)" macro only includes that option when it's
+# supported by the compiler used. It may only work on Debian systems.
+
+# Wdate-time was added in gcc-4.9
+EXTRA_CFLAGS += $(call cc-option,-Werror=date-time)
+# Wincompatible-pointer-types was added in gcc-5.0
+EXTRA_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
+
EXTRA_CFLAGS += -Wno-unused-variable
EXTRA_CFLAGS += -Wno-unused-value
EXTRA_CFLAGS += -Wno-unused-label
@@ -14,10 +22,16 @@ EXTRA_CFLAGS += -Wno-unused-parameter
EXTRA_CFLAGS += -Wno-unused-function
EXTRA_CFLAGS += -Wno-unused
-EXTRA_CFLAGS += -Wno-uninitialized
+# Relax some warnings from '-Wextra' so we won't get flooded with warnings
+EXTRA_CFLAGS += -Wno-sign-compare
+EXTRA_CFLAGS += -Wno-missing-field-initializers
+
+#EXTRA_CFLAGS += -Wno-uninitialized
EXTRA_CFLAGS += -I$(src)/include
+EXTRA_LDFLAGS += --strip-debug
+
CONFIG_AUTOCFG_CP = n
CONFIG_RTL8192C = y
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ap.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ap.c
@@ -210,7 +210,7 @@ void rtw_add_bcn_ie(_adapter *padapter,
PNDIS_802_11_VARIABLE_IEs pIE;
u8 bmatch = _FALSE;
u8 *pie = pnetwork->IEs;
- u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
+ u8 *p=NULL, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
@@ -250,6 +250,9 @@ void rtw_add_bcn_ie(_adapter *padapter,
dst_ie = (p+ielen);
}
+ if(dst_ie == NULL)
+ return;
+
if(remainder_ielen>0)
{
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
@@ -357,7 +360,7 @@ void expire_timeout_chk(_adapter *padapt
{
_irqL irqL;
_list *phead, *plist;
- u8 updated;
+ u8 updated = _FALSE;
struct sta_info *psta=NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
u8 chk_alive_num = 0;
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ieee80211.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ieee80211.c
@@ -1859,7 +1859,8 @@ int rtw_action_frame_parse(const u8 *fra
{
const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
u16 fc;
- u8 c, a;
+ u8 c;
+ u8 a = ACT_PUBLIC_MAX;
fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl);
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_set.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_set.c
@@ -43,7 +43,7 @@ extern void indicate_wx_scan_complete_ev
(addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \
)
-u8 rtw_validate_bssid(u8 *bssid)
+u8 rtw_validate_bssid(const u8 *bssid)
{
u8 ret = _TRUE;
@@ -535,7 +535,8 @@ _func_exit_;
}
-u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
+u8 rtw_set_802_11_connect(_adapter *padapter, const u8 *bssid
+ , NDIS_802_11_SSID *ssid)
{
_irqL irqL;
u8 status = _SUCCESS;
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c
@@ -2454,7 +2454,7 @@ unsigned int OnDeAuth(_adapter *padapter
psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
if(psta)
{
- u8 updated;
+ u8 updated = _FALSE;
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
@@ -2548,7 +2548,7 @@ unsigned int OnDisassoc(_adapter *padapt
psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
if(psta)
{
- u8 updated;
+ u8 updated = _FALSE;
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
@@ -5663,7 +5663,7 @@ unsigned int on_action_public_p2p(union
// Commented by Kurt 20120113
// Get peer_dev_addr here if peer doesn't issue prov_disc frame.
- if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) );
+ if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
@@ -11932,7 +11932,7 @@ u8 setkey_hdl(_adapter *padapter, u8 *pb
u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
{
u16 ctrl=0;
- u8 cam_id;//cam_entry
+ u8 cam_id=0;//cam_entry
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_p2p.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_p2p.c
@@ -4896,9 +4896,9 @@ void init_wifidirect_info( _adapter* pad
#endif
#ifdef CONFIG_CONCURRENT_MODE
_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
- struct wifidirect_info *pbuddy_wdinfo;
- struct mlme_priv *pbuddy_mlmepriv;
- struct mlme_ext_priv *pbuddy_mlmeext;
+ struct wifidirect_info *pbuddy_wdinfo = NULL;
+ struct mlme_priv *pbuddy_mlmepriv = NULL;
+ struct mlme_ext_priv *pbuddy_mlmeext = NULL;
#endif
pwdinfo = &padapter->wdinfo;
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_recv.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_recv.c
@@ -3894,7 +3894,7 @@ int process_recv_indicatepkts(_adapter *
}
-int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
+static int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
{
int ret = _SUCCESS;
struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
@@ -3935,7 +3935,7 @@ exit:
return ret;
}
-int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
+static int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
{
int ret = _SUCCESS;
union recv_frame *orig_prframe = prframe;
@@ -4107,8 +4107,7 @@ _recv_data_drop:
}
-int recv_func(_adapter *padapter, union recv_frame *rframe);
-int recv_func(_adapter *padapter, union recv_frame *rframe)
+static int recv_func(_adapter *padapter, union recv_frame *rframe)
{
int ret;
struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_sta_mgt.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_sta_mgt.c
@@ -685,7 +685,7 @@ _func_exit_;
}
/* any station allocated can be searched by hash list */
-struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
+struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr)
{
_irqL irqL;
@@ -696,7 +696,7 @@ struct sta_info *rtw_get_stainfo(struct
u32 index;
- u8 *addr;
+ const u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_wlan_util.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_wlan_util.c
@@ -853,7 +853,7 @@ void flush_all_cam_entry(_adapter *padap
{
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta;
- u8 cam_id;//cam_entry
+ u8 cam_id=0;//cam_entry
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
if(psta) {
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_xmit.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_xmit.c
@@ -2590,7 +2590,7 @@ exit:
s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
{
_irqL irqL;
- _queue *queue;
+ _queue *queue = NULL;
_adapter *padapter = pxmitpriv->adapter;
_pkt *pndis_pkt = NULL;
--- a/drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c
@@ -373,7 +373,7 @@ static void getTxPowerWriteValByRegulato
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
struct dm_priv *pdmpriv = &pHalData->dmpriv;
- u8 i, chnlGroup, pwr_diff_limit[4];
+ u8 i, chnlGroup = 0, pwr_diff_limit[4];
u32 writeVal, customer_limit, rf;
//
@@ -615,7 +615,7 @@ phy_RF6052_Config_ParaFile(
IN PADAPTER Adapter
)
{
- u32 u4RegValue;
+ u32 u4RegValue=0;
u8 eRFPath;
BB_REGISTER_DEFINITION_T *pPhyReg;
--- a/drivers/net/wireless/realtek/rtl8192cu/include/autoconf.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/autoconf.h
@@ -31,10 +31,11 @@
#define PLATFORM_LINUX 1
-//#define CONFIG_IOCTL_CFG80211 1
+#define CONFIG_IOCTL_CFG80211 1
#ifdef CONFIG_IOCTL_CFG80211
- //#define RTW_USE_CFG80211_STA_EVENT /* Indecate new sta asoc through cfg80211_new_sta */
- #define CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER
+ /* Indicate new sta asoc through cfg80211_new_sta */
+ #define RTW_USE_CFG80211_STA_EVENT
+ /*#define CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER*/
//#define CONFIG_DEBUG_CFG80211 1
//#define CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2
#define CONFIG_SET_SCAN_DENY_TIMER
@@ -324,7 +325,7 @@
//#define DBG_MEMORY_LEAK 1
-#define DBG_CONFIG_ERROR_DETECT
+/*#define DBG_CONFIG_ERROR_DETECT*/
//#define DBG_CONFIG_ERROR_RESET
//TX use 1 urb
--- a/drivers/net/wireless/realtek/rtl8192cu/include/ioctl_cfg80211.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/ioctl_cfg80211.h
@@ -149,8 +149,15 @@ bool rtw_cfg80211_pwr_mgmt(_adapter *ada
#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->pnetdev, freq, buf, len, gfp)
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->pnetdev, freq, sig_dbm, buf, len, gfp)
-#else
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0))
#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len, gfp)
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0))
+/* 3.12 added a flags argument which is just set to zero*/
+#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) \
+ cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len, 0, gfp)
+#else
+#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) \
+ cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len, 0)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
--- a/drivers/net/wireless/realtek/rtl8192cu/include/osdep_service.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/osdep_service.h
@@ -1395,8 +1395,8 @@ void _rtw_usb_buffer_free(struct usb_dev
extern void* rtw_malloc2d(int h, int w, int size);
extern void rtw_mfree2d(void *pbuf, int h, int w, int size);
-extern void _rtw_memcpy(void* dec, void* sour, u32 sz);
-extern int _rtw_memcmp(void *dst, void *src, u32 sz);
+extern void _rtw_memcpy(void *dec, const void *sour, u32 sz);
+extern int _rtw_memcmp(const void *dst, const void *src, u32 sz);
extern void _rtw_memset(void *pbuf, int c, u32 sz);
extern void _rtw_init_listhead(_list *list);
--- a/drivers/net/wireless/realtek/rtl8192cu/include/rtw_debug.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/rtw_debug.h
@@ -313,15 +313,15 @@ extern u32 GlobalDebugLevel;
#if defined (_dbgdump)
#undef DBG_871X
// #define DBG_871X _dbgdump
- #define DBG_871X(...) LOG_LEVEL(_drv_emerg_ , __VA_ARGS__)
+ #define DBG_871X(...) LOG_LEVEL(_drv_debug_ , __VA_ARGS__)
#undef MSG_8192C
// #define MSG_8192C _dbgdump
- #define MSG_8192C(...) LOG_LEVEL(_drv_emerg_ , __VA_ARGS__)
+ #define MSG_8192C(...) LOG_LEVEL(_drv_info_ , __VA_ARGS__)
#undef DBG_8192C
// #define DBG_8192C _dbgdump
- #define DBG_8192C(...) LOG_LEVEL(_drv_emerg_ , __VA_ARGS__)
+ #define DBG_8192C(...) LOG_LEVEL(_drv_debug_ , __VA_ARGS__)
#undef WRN_8192C
--- a/drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl_set.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl_set.h
@@ -63,10 +63,11 @@ u8 rtw_set_802_11_bssid_list_scan(_adapt
u8 rtw_set_802_11_infrastructure_mode(_adapter * padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype);
u8 rtw_set_802_11_remove_wep(_adapter * padapter, u32 keyindex);
u8 rtw_set_802_11_ssid(_adapter * padapter, NDIS_802_11_SSID * ssid);
-u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid);
+u8 rtw_set_802_11_connect(_adapter *padapter, const u8 *bssid
+ , NDIS_802_11_SSID *ssid);
u8 rtw_set_802_11_remove_key(_adapter * padapter, NDIS_802_11_REMOVE_KEY * key);
-u8 rtw_validate_bssid(u8 *bssid);
+u8 rtw_validate_bssid(const u8 *bssid);
u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid);
u16 rtw_get_cur_max_rate(_adapter *adapter);
--- a/drivers/net/wireless/realtek/rtl8192cu/include/sta_info.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/sta_info.h
@@ -395,7 +395,7 @@ struct sta_priv {
};
-__inline static u32 wifi_mac_hash(u8 *mac)
+__inline static u32 wifi_mac_hash(const u8 *mac)
{
u32 x;
@@ -423,7 +423,7 @@ struct sta_info *rtw_get_stainfo_by_offs
extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr);
extern u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta);
extern void rtw_free_all_stainfo(_adapter *padapter);
-extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr);
+extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr);
extern u32 rtw_init_bcmc_stainfo(_adapter* padapter);
extern struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter);
extern u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr);
--- a/drivers/net/wireless/realtek/rtl8192cu/include/wifi.h
+++ b/drivers/net/wireless/realtek/rtl8192cu/include/wifi.h
@@ -425,7 +425,7 @@ enum WIFI_REG_DOMAIN {
(addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \
)
-__inline static int IS_MCAST(unsigned char *da)
+__inline static int IS_MCAST(const unsigned char *da)
{
if ((*da) & 0x01)
return _TRUE;
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_cfg80211.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_cfg80211.c
@@ -57,7 +57,7 @@ static const u32 rtw_cipher_suites[] = {
}
#define CHAN2G(_channel, _freq, _flags) { \
- .band = IEEE80211_BAND_2GHZ, \
+ .band = NL80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_channel), \
.flags = (_flags), \
@@ -66,7 +66,7 @@ static const u32 rtw_cipher_suites[] = {
}
#define CHAN5G(_channel, _flags) { \
- .band = IEEE80211_BAND_5GHZ, \
+ .band = NL80211_BAND_5GHZ, \
.center_freq = 5000 + (5 * (_channel)), \
.hw_value = (_channel), \
.flags = (_flags), \
@@ -166,18 +166,18 @@ void rtw_5g_rates_init(struct ieee80211_
}
struct ieee80211_supported_band *rtw_spt_band_alloc(
- enum ieee80211_band band
+ enum nl80211_band band
)
{
struct ieee80211_supported_band *spt_band = NULL;
int n_channels, n_bitrates;
- if(band == IEEE80211_BAND_2GHZ)
+ if(band == NL80211_BAND_2GHZ)
{
n_channels = RTW_2G_CHANNELS_NUM;
n_bitrates = RTW_G_RATES_NUM;
}
- else if(band == IEEE80211_BAND_5GHZ)
+ else if(band == NL80211_BAND_5GHZ)
{
n_channels = RTW_5G_CHANNELS_NUM;
n_bitrates = RTW_A_RATES_NUM;
@@ -201,12 +201,12 @@ struct ieee80211_supported_band *rtw_spt
spt_band->n_channels = n_channels;
spt_band->n_bitrates = n_bitrates;
- if(band == IEEE80211_BAND_2GHZ)
+ if(band == NL80211_BAND_2GHZ)
{
rtw_2g_channels_init(spt_band->channels);
rtw_2g_rates_init(spt_band->bitrates);
}
- else if(band == IEEE80211_BAND_5GHZ)
+ else if(band == NL80211_BAND_5GHZ)
{
rtw_5g_channels_init(spt_band->channels);
rtw_5g_rates_init(spt_band->bitrates);
@@ -221,18 +221,18 @@ exit:
void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
{
- u32 size;
+ u32 size = 0;
if(!spt_band)
return;
- if(spt_band->band == IEEE80211_BAND_2GHZ)
+ if(spt_band->band == NL80211_BAND_2GHZ)
{
size = sizeof(struct ieee80211_supported_band)
+ sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
+ sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
}
- else if(spt_band->band == IEEE80211_BAND_5GHZ)
+ else if(spt_band->band == NL80211_BAND_5GHZ)
{
size = sizeof(struct ieee80211_supported_band)
+ sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
@@ -301,12 +301,12 @@ static int rtw_ieee80211_channel_to_freq
/* see 802.11 17.3.8.3.2 and Annex J
* there are overlapping channel numbers in 5GHz and 2GHz bands */
- if (band == IEEE80211_BAND_5GHZ) {
+ if (band == NL80211_BAND_5GHZ) {
if (chan >= 182 && chan <= 196)
return 4000 + chan * 5;
else
return 5000 + chan * 5;
- } else { /* IEEE80211_BAND_2GHZ */
+ } else { /* NL80211_BAND_2GHZ */
if (chan == 14)
return 2484;
else if (chan < 14)
@@ -331,7 +331,7 @@ static int rtw_cfg80211_inform_bss(_adap
u8 *notify_ie;
size_t notify_ielen;
s32 notify_signal;
- u8 buf[MAX_BSSINFO_LEN], *pbuf;
+ u8 *buf, *pbuf;
size_t len,bssinf_len=0;
struct rtw_ieee80211_hdr *pwlanhdr;
unsigned short *fctrl;
@@ -391,9 +391,9 @@ static int rtw_cfg80211_inform_bss(_adap
DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, NL80211_BAND_5GHZ);
notify_channel = ieee80211_get_channel(wiphy, freq);
pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
@@ -424,9 +424,9 @@ static int rtw_cfg80211_inform_bss(_adap
channel = pnetwork->network.Configuration.DSConfig;
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
notify_channel = ieee80211_get_channel(wiphy, freq);
@@ -459,6 +459,7 @@ static int rtw_cfg80211_inform_bss(_adap
DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp);
*/
+ buf = rtw_zmalloc(MAX_BSSINFO_LEN);
pbuf = buf;
pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
@@ -486,6 +487,8 @@ static int rtw_cfg80211_inform_bss(_adap
_rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
len += pnetwork->network.IELength;
+ rtw_mfree(buf, MAX_BSSINFO_LEN);
+
//#ifdef CONFIG_P2P
//if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
//{
@@ -569,15 +572,19 @@ int rtw_cfg80211_check_bss(_adapter *pad
return _FALSE;
if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, NL80211_BAND_5GHZ);
notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
pnetwork->MacAddress, pnetwork->Ssid.Ssid,
pnetwork->Ssid.SsidLength,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+#else
+ IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
+#endif
return (bss!=NULL);
}
@@ -626,9 +633,9 @@ void rtw_cfg80211_indicate_connect(_adap
u16 channel = cur_network->network.Configuration.DSConfig;
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
notify_channel = ieee80211_get_channel(wiphy, freq);
#endif
@@ -700,13 +707,16 @@ void rtw_cfg80211_indicate_disconnect(_a
if (!padapter->mlmepriv.not_indic_disco) {
DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
- if(pwdev->sme_state==CFG80211_SME_CONNECTING)
+ if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
- else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
+ } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
- //else
- //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
+#else
+ cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, false, GFP_ATOMIC);
+#endif
+ }
DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
}
@@ -1549,7 +1559,7 @@ static int cfg80211_rtw_set_default_key(
static int cfg80211_rtw_get_station(struct wiphy *wiphy,
struct net_device *ndev,
- u8 *mac, struct station_info *sinfo)
+ const u8 *mac, struct station_info *sinfo)
{
int ret = 0;
_adapter *padapter = wiphy_to_adapter(wiphy);
@@ -1589,16 +1599,32 @@ static int cfg80211_rtw_get_station(stru
goto exit;
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+#else
sinfo->filled |= STATION_INFO_SIGNAL;
+#endif
sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+#else
sinfo->filled |= STATION_INFO_TX_BITRATE;
+#endif
sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
+#else
sinfo->filled |= STATION_INFO_RX_PACKETS;
+#endif
sinfo->rx_packets = sta_rx_data_pkts(psta);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
+#else
sinfo->filled |= STATION_INFO_TX_PACKETS;
+#endif
sinfo->tx_packets = psta->sta_stats.tx_pkts;
}
@@ -1789,7 +1815,15 @@ void rtw_cfg80211_indicate_scan_done(str
}
else
{
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
cfg80211_scan_done(pwdev_priv->scan_request, aborted);
+ #else
+ struct cfg80211_scan_info info = {
+ .aborted = aborted,
+ };
+
+ cfg80211_scan_done(pwdev_priv->scan_request, &info);
+ #endif
}
pwdev_priv->scan_request = NULL;
@@ -2419,7 +2453,7 @@ static int rtw_cfg80211_set_key_mgt(stru
return 0;
}
-static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
+static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, const u8 *pie, size_t ielen)
{
u8 *buf=NULL, *pos=NULL;
u32 left;
@@ -3089,7 +3123,9 @@ void rtw_cfg80211_indicate_sta_assoc(_ad
ie_offset = _REASOCREQ_IE_OFFSET_;
sinfo.filled = 0;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0))
sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
+#endif
sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
@@ -3097,9 +3133,9 @@ void rtw_cfg80211_indicate_sta_assoc(_ad
#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
channel = pmlmeext->cur_channel;
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
#ifdef COMPAT_KERNEL_RELEASE
rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
@@ -3142,9 +3178,9 @@ void rtw_cfg80211_indicate_sta_disassoc(
#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
channel = pmlmeext->cur_channel;
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
pmgmt_frame = mgmt_buf;
pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
@@ -3387,7 +3423,11 @@ static const struct net_device_ops rtw_c
};
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
+static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, unsigned char name_assign_type, struct net_device **ndev)
+#else
static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
+#endif
{
int ret = 0;
struct net_device* mon_ndev = NULL;
@@ -3418,6 +3458,9 @@ static int rtw_cfg80211_add_monitor_if(_
mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
strncpy(mon_ndev->name, name, IFNAMSIZ);
mon_ndev->name[IFNAMSIZ - 1] = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
+ mon_ndev->name_assign_type = name_assign_type;
+#endif
mon_ndev->destructor = rtw_ndev_destructor;
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
@@ -3482,6 +3525,9 @@ static int
#else
char *name,
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
+ unsigned char name_assign_type,
+#endif
enum nl80211_iftype type, u32 *flags, struct vif_params *params)
{
int ret = 0;
@@ -3499,7 +3545,11 @@ static int
ret = -ENODEV;
break;
case NL80211_IFTYPE_MONITOR:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
+ ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, name_assign_type, &ndev);
+#else
ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
+#endif
break;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
@@ -3760,7 +3810,7 @@ static int cfg80211_rtw_stop_ap(struct w
#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
- u8 *mac, struct station_parameters *params)
+ const u8 *mac, struct station_parameters *params)
{
DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
@@ -3768,12 +3818,19 @@ static int cfg80211_rtw_add_station(stru
}
static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
- u8 *mac)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
+ u8 *mac) {
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0))
+ const u8 *mac) {
+#else
+ struct station_del_parameters *params)
{
+ const u8 *mac = params->mac;
+#endif
int ret=0;
_irqL irqL;
_list *phead, *plist;
- u8 updated;
+ u8 updated = _FALSE;
struct sta_info *psta = NULL;
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
@@ -3859,7 +3916,7 @@ static int cfg80211_rtw_del_station(stru
}
static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
- u8 *mac, struct station_parameters *params)
+ const u8 *mac, struct station_parameters *params)
{
DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
@@ -3950,9 +4007,9 @@ void rtw_cfg80211_rx_action_p2p(_adapter
indicate:
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
@@ -3990,9 +4047,9 @@ void rtw_cfg80211_rx_p2p_action_public(_
indicate:
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
@@ -4020,9 +4077,9 @@ void rtw_cfg80211_rx_action(_adapter *ad
DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
else
- freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+ freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
@@ -4643,6 +4700,9 @@ static int cfg80211_rtw_mgmt_tx(struct w
#else
struct net_device *ndev,
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
+ struct cfg80211_mgmt_tx_params *params,
+#else
struct ieee80211_channel *chan,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
bool offchan,
@@ -4663,8 +4723,15 @@ static int cfg80211_rtw_mgmt_tx(struct w
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
bool dont_wait_for_ack,
#endif
+#endif
u64 *cookie)
{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
+ struct ieee80211_channel *chan = params->chan;
+ const u8 *buf = params->buf;
+ size_t len = params->len;
+#endif
+
_adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy);
struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
int ret = 0;
@@ -5199,7 +5266,7 @@ static struct cfg80211_ops rtw_cfg80211_
#endif
};
-static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
+static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum nl80211_band band, u8 rf_type)
{
#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
@@ -5223,7 +5290,7 @@ static void rtw_cfg80211_init_ht_capab(s
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
/*
- *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ *hw->wiphy->bands[NL80211_BAND_2GHZ]
*base on ant_num
*rx_mask: RX mask
*if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
@@ -5268,16 +5335,16 @@ void rtw_cfg80211_init_wiphy(_adapter *p
/* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
{
- bands = wiphy->bands[IEEE80211_BAND_2GHZ];
+ bands = wiphy->bands[NL80211_BAND_2GHZ];
if(bands)
- rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
+ rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_2GHZ, rf_type);
}
/* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
{
- bands = wiphy->bands[IEEE80211_BAND_5GHZ];
+ bands = wiphy->bands[NL80211_BAND_5GHZ];
if(bands)
- rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
+ rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_5GHZ, rf_type);
}
}
@@ -5348,9 +5415,9 @@ static void rtw_cfg80211_preinit_wiphy(_
wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
/* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
- wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
+ wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(NL80211_BAND_2GHZ);
/* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
- wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
+ wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(NL80211_BAND_5GHZ);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
@@ -5402,8 +5469,11 @@ int rtw_wdev_alloc(_adapter *padapter, s
}
wdev->wiphy = wiphy;
wdev->netdev = pnetdev;
- //wdev->iftype = NL80211_IFTYPE_STATION;
- wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
+
+ wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
+ // Must sync with _rtw_init_mlme_priv()
+ // pmlmepriv->fw_state = WIFI_STATION_STATE
+ //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
padapter->rtw_wdev = wdev;
pnetdev->ieee80211_ptr = wdev;
@@ -5456,8 +5526,8 @@ void rtw_wdev_free(struct wireless_dev *
pwdev_priv = wdev_to_priv(wdev);
- rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
- rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
+ rtw_spt_band_free(wdev->wiphy->bands[NL80211_BAND_2GHZ]);
+ rtw_spt_band_free(wdev->wiphy->bands[NL80211_BAND_5GHZ]);
wiphy_free(wdev->wiphy);
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_linux.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_linux.c
@@ -6584,7 +6584,6 @@ static int rtw_dbg_port(struct net_devic
case 0x01: //dbg mode
padapter->recvpriv.is_signal_dbg = 1;
extra_arg = extra_arg>100?100:extra_arg;
- extra_arg = extra_arg<0?0:extra_arg;
padapter->recvpriv.signal_strength_dbg=extra_arg;
break;
}
@@ -6956,7 +6955,7 @@ static int rtw_dbg_port(struct net_devic
{
struct registry_priv *pregpriv = &padapter->registrypriv;
// 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
- if( pregpriv && extra_arg >= 0 && extra_arg < 3 )
+ if( pregpriv && extra_arg < 3 )
{
pregpriv->ampdu_enable= extra_arg;
DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/os_intfs.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/os_intfs.c
@@ -945,8 +945,14 @@ unsigned int rtw_classify8021d(struct sk
return dscp >> 5;
}
-static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb,
- void *accel_priv, select_queue_fallback_t fallback)
+static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
+ , void *accel_priv
+#endif
+#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,14,0))
+ , select_queue_fallback_t fallback
+#endif
+)
{
_adapter *padapter = rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -1057,6 +1063,10 @@ int rtw_init_netdev_name(struct net_devi
return 0;
}
+static const struct device_type wlan_type = {
+ .name = "wlan",
+};
+
struct net_device *rtw_init_netdev(_adapter *old_padapter)
{
_adapter *padapter;
@@ -1072,6 +1082,7 @@ struct net_device *rtw_init_netdev(_adap
if (!pnetdev)
return NULL;
+ pnetdev->dev.type = &wlan_type;
padapter = rtw_netdev_priv(pnetdev);
padapter->pnetdev = pnetdev;
@@ -1681,9 +1692,6 @@ int _netdev_vir_if_open(struct net_devic
padapter->bup = _TRUE;
padapter->hw_init_completed = _TRUE;
-
- rtw_start_mbssid_cam(padapter);//start mbssid_cam after bup = _TRUE & hw_init_completed = _TRUE
-
}
padapter->net_closed = _FALSE;
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/recv_linux.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/recv_linux.c
@@ -136,7 +136,7 @@ int rtw_os_recvbuf_resource_free(_adapte
void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup)
{
#ifdef CONFIG_IOCTL_CFG80211
- enum nl80211_key_type key_type;
+ enum nl80211_key_type key_type = 0;
#endif
union iwreq_data wrqu;
struct iw_michaelmicfailure ev;
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/rtw_android.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/rtw_android.c
@@ -96,13 +96,7 @@ typedef struct cmd_tlv {
#endif /* PNO_SUPPORT */
typedef struct android_wifi_priv_cmd {
-
-#ifdef CONFIG_COMPAT
- compat_uptr_t buf;
-#else
char *buf;
-#endif
-
int used_len;
int total_len;
} android_wifi_priv_cmd;
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/usb_intf.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/usb_intf.c
@@ -102,6 +102,7 @@ static void rtw_dev_remove(struct usb_in
{USB_DEVICE(0x103C, 0x1629)},/* HP - Lite-On ,8188CUS Slim Combo */ \
{USB_DEVICE(0x2001, 0x3308)},/* D-Link - Alpha */ \
{USB_DEVICE(0x050D, 0x1102)},/* Belkin - Edimax */ \
+ {USB_DEVICE(0x050D, 0x11F2)},/* ISY - Edimax */ \
{USB_DEVICE(0x2019, 0xAB2A)},/* Planex - Abocom */ \
{USB_DEVICE(0x20F4, 0x648B)},/* TRENDnet - Cameo */ \
{USB_DEVICE(0x4855, 0x0090)},/* - Feixun */ \
@@ -110,6 +111,8 @@ static void rtw_dev_remove(struct usb_in
{USB_DEVICE(0x0BDA, 0x5088)},/* Thinkware - CC&C */ \
{USB_DEVICE(0x4856, 0x0091)},/* NetweeN - Feixun */ \
{USB_DEVICE(0x0846, 0x9041)}, /* Netgear - Cameo */ \
+ {USB_DEVICE(0x0846, 0x9042)}, /* On Networks - N150MA */ \
+ {USB_DEVICE(0x0846, 0x9043)}, /* Netgear N150 -WNA1000M */ \
{USB_DEVICE(0x2019, 0x4902)},/* Planex - Etop */ \
{USB_DEVICE(0x2019, 0xAB2E)},/* SW-WF02-AD15 -Abocom */ \
{USB_DEVICE(0x2001, 0x330B)}, /* D-LINK - T&W */ \
@@ -117,6 +120,7 @@ static void rtw_dev_remove(struct usb_in
{USB_DEVICE(0x0B05, 0x17BA)}, /* ASUS - Edimax */ \
{USB_DEVICE(0x0BDA, 0x1E1E)}, /* Intel - - */ \
{USB_DEVICE(0x04BB, 0x094c)}, /* I-O DATA - Edimax */ \
+ {USB_DEVICE(0X0BDA, 0x8176)}, /* TP-Link TL-WN723N */ \
/****** 8188CTV ********/ \
{USB_DEVICE(0xCDAB, 0x8011)}, /* - - compare */ \
{USB_DEVICE(0x0BDA, 0x0A8A)}, /* Sony - Foxconn */ \
@@ -991,7 +995,7 @@ static int rtw_resume(struct usb_interfa
int rtw_resume_process(_adapter *padapter)
{
struct net_device *pnetdev;
- struct pwrctrl_priv *pwrpriv;
+ struct pwrctrl_priv *pwrpriv=NULL;
int ret = -1;
u32 start_time = rtw_get_current_time();
_func_enter_;
@@ -1054,7 +1058,8 @@ exit:
rtw_unlock_suspend();
#endif //CONFIG_RESUME_IN_WORKQUEUE
- pwrpriv->bInSuspend = _FALSE;
+ if (pwrpriv)
+ pwrpriv->bInSuspend = _FALSE;
DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__
, ret, rtw_get_passing_time_ms(start_time));
--- a/drivers/net/wireless/realtek/rtl8192cu/os_dep/osdep_service.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/os_dep/osdep_service.c
@@ -790,7 +790,7 @@ void rtw_mfree2d(void *pbuf, int h, int
rtw_mfree((u8 *)pbuf, h*sizeof(void*) + w*h*size);
}
-void _rtw_memcpy(void* dst, void* src, u32 sz)
+void _rtw_memcpy(void* dst, const void* src, u32 sz)
{
#if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
@@ -807,7 +807,7 @@ void _rtw_memcpy(void* dst, void* src, u
}
-int _rtw_memcmp(void *dst, void *src, u32 sz)
+int _rtw_memcmp(const void *dst, const void *src, u32 sz)
{
#if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)

@ -1,157 +0,0 @@
From 2d888bed201222f294deb8a27641f7f9919dab54 Mon Sep 17 00:00:00 2001
From: Cheong2K <cheong@redbear.cc>
Date: Fri, 26 Feb 2016 18:20:10 +0800
Subject: [PATCH] brcm: adds support for BCM43341 wifi
brcmfmac: Disable power management
Disable wireless power saving in the brcmfmac WLAN driver. This is a
temporary measure until the connectivity loss resulting from power
saving is resolved.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
brcmfmac: Use original country code as a fallback
Commit 73345fd212980d2e28a5c6d83801c903bd773680:
brcmfmac: Configure country code using device specific settings
prevents region codes from working on devices that lack a region code
translation table. In the event of an absent table, preserve the old
behaviour of using the provided code as-is.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
brcmfmac: Plug memory leak in brcmf_fill_bss_param
See: https://github.com/raspberrypi/linux/issues/1471
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
brcmfmac: do not use internal roaming engine by default
Some evidence of curing disconnects with this disabled, so make it a default.
Can be overridden with module parameter roamoff=0
See: http://projectable.me/optimize-my-pi-wi-fi/
brcmfmac: Change stop_ap sequence
Patch from Broadcom/Cypress to resolve a customer error
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 31 ++++++++++++++++------
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++
.../broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
4 files changed, 27 insertions(+), 9 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2756,6 +2756,8 @@ brcmf_cfg80211_set_power_mgmt(struct wip
* preference in cfg struct to apply this to
* FW later while initializing the dongle
*/
+ pr_info("power management disabled\n");
+ enabled = false;
cfg->pwr_save = enabled;
if (!check_vif_up(ifp->vif)) {
@@ -4750,12 +4752,15 @@ static int brcmf_cfg80211_stop_ap(struct
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0)
brcmf_err("BRCMF_C_DOWN error %d\n", err);
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
- if (err < 0)
- brcmf_err("setting AP mode failed %d\n", err);
+
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
if (err < 0)
brcmf_err("setting INFRA mode failed %d\n", err);
+
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
+ if (err < 0)
+ brcmf_err("setting AP mode failed %d\n", err);
+
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
@@ -6737,12 +6742,18 @@ static s32 brcmf_translate_country_code(
struct brcmfmac_pd_cc *country_codes;
struct brcmfmac_pd_cc_entry *cc;
s32 found_index;
+ char ccode[BRCMF_COUNTRY_BUF_SZ];
+ int rev;
int i;
+ memcpy(ccode, alpha2, sizeof(ccode));
+ rev = -1;
+
country_codes = drvr->settings->country_codes;
if (!country_codes) {
- brcmf_dbg(TRACE, "No country codes configured for device\n");
- return -EINVAL;
+ brcmf_dbg(TRACE, "No country codes configured for device"
+ " - use requested value\n");
+ goto use_input_value;
}
if ((alpha2[0] == ccreq->country_abbrev[0]) &&
@@ -6766,10 +6777,14 @@ static s32 brcmf_translate_country_code(
brcmf_dbg(TRACE, "No country code match found\n");
return -EINVAL;
}
- memset(ccreq, 0, sizeof(*ccreq));
- ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
- memcpy(ccreq->ccode, country_codes->table[found_index].cc,
+ rev = country_codes->table[found_index].rev;
+ memcpy(ccode, country_codes->table[found_index].cc,
BRCMF_COUNTRY_BUF_SZ);
+
+use_input_value:
+ memset(ccreq, 0, sizeof(*ccreq));
+ ccreq->rev = cpu_to_le32(rev);
+ memcpy(ccreq->ccode, ccode, sizeof(ccode));
ccreq->country_abbrev[0] = alpha2[0];
ccreq->country_abbrev[1] = alpha2[1];
ccreq->country_abbrev[2] = 0;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -69,7 +69,7 @@ static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0);
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
-static int brcmf_roamoff;
+static int brcmf_roamoff = 1;
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -604,6 +604,7 @@ BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-s
BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt");
BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt");
BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt");
+BRCMF_FW_NVRAM_DEF(43341, "brcmfmac43341-sdio.bin", "brcmfmac43341-sdio.txt");
BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt");
BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt");
BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt");
@@ -621,6 +622,7 @@ static struct brcmf_firmware_mapping brc
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
+ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43341),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -36,6 +36,7 @@
#define BRCM_CC_4330_CHIP_ID 0x4330
#define BRCM_CC_4334_CHIP_ID 0x4334
#define BRCM_CC_43340_CHIP_ID 43340
+#define BRCM_CC_43341_CHIP_ID 43341
#define BRCM_CC_43362_CHIP_ID 43362
#define BRCM_CC_4335_CHIP_ID 0x4335
#define BRCM_CC_4339_CHIP_ID 0x4339

@ -1,33 +0,0 @@
From d2ab394e853bafeeadb911155b1621886c299d5f Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sun, 15 Jan 2017 07:25:18 -0800
Subject: [PATCH] ARM64: Fix build break for RTL8187/RTL8192CU wifi
These drivers use an ASM function from the base
system to compute the ipv6 checksum. These functions
are not available on ARM64, probably because nobody
has bother to write them. The base system does have
a generic "C" version, so a simple fix is to include
the header to use the generic version on ARM64 only.
A longer term solution would be to submit the necessary
ASM function to the upstream source.
With this change, these drivers now compile without
any errors on ARM64.
Signed-off-by: Michael Zoran <mzoran@crowfest.net>
---
drivers/net/wireless/realtek/rtl8192cu/core/rtw_br_ext.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/realtek/rtl8192cu/core/rtw_br_ext.c
+++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_br_ext.c
@@ -51,6 +51,7 @@
#include <linux/icmpv6.h>
#include <net/ndisc.h>
#include <net/checksum.h>
+#include <net/ip6_checksum.h>
#endif
#endif

@ -0,0 +1,33 @@
From 92105f7981fd207add7a09ace4570c9cd74f8757 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] config: Enable regulator support
Signed-off-by: Matthias Reichl <hias@horus.com>
---
arch/arm/configs/bcm2709_defconfig | 2 ++
arch/arm/configs/bcmrpi_defconfig | 2 ++
2 files changed, 4 insertions(+)
--- a/arch/arm/configs/bcm2709_defconfig
+++ b/arch/arm/configs/bcm2709_defconfig
@@ -664,6 +664,8 @@ CONFIG_STMPE_SPI=y
CONFIG_MFD_ARIZONA_I2C=m
CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_WM5102=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -658,6 +658,8 @@ CONFIG_STMPE_SPI=y
CONFIG_MFD_ARIZONA_I2C=m
CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_WM5102=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y

@ -0,0 +1,33 @@
From 06b6fe1687cc560f36976cef615d38071ae07867 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] BCM270x DT: expose 3.3V and 5V system rails
Signed-off-by: Matthias Reichl <hias@horus.com>
---
arch/arm/boot/dts/bcm270x.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/arch/arm/boot/dts/bcm270x.dtsi
+++ b/arch/arm/boot/dts/bcm270x.dtsi
@@ -138,4 +138,20 @@
status = "disabled";
};
};
+
+ vdd_5v0_reg: fixedregulator_5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: fixedregulator_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
};

@ -0,0 +1,273 @@
From 05798b17d672768e9e2c54c0c94df2ef019afe95 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] BCM270x DT: Consolidate audio card overlays
Reference 3.3V / 5V system rails instead of instantiating local
regulators.
Add missing power supply properties for codecs where these are
required according to the DT bindings docs.
Signed-off-by: Matthias Reichl <hias@horus.com>
---
.../arm/boot/dts/overlays/adau1977-adc-overlay.dts | 19 ++--------
.../dts/overlays/akkordion-iqdacplus-overlay.dts | 3 ++
.../dts/overlays/hifiberry-dacplus-overlay.dts | 3 ++
.../boot/dts/overlays/hifiberry-digi-overlay.dts | 2 +
.../dts/overlays/hifiberry-digi-pro-overlay.dts | 2 +
arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 3 ++
.../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 3 ++
.../overlays/iqaudio-digi-wm8804-audio-overlay.dts | 4 +-
.../arm/boot/dts/overlays/justboom-dac-overlay.dts | 3 ++
.../boot/dts/overlays/justboom-digi-overlay.dts | 2 +
arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 4 ++
.../overlays/rra-digidac1-wm8741-audio-overlay.dts | 44 +++-------------------
12 files changed, 36 insertions(+), 56 deletions(-)
--- a/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts
+++ b/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts
@@ -6,19 +6,6 @@
compatible = "brcm,bcm2708";
fragment@0 {
- target = <&soc>;
-
- __overlay__ {
- codec_supply: fixedregulator@0 {
- compatible = "regulator-fixed";
- regulator-name = "AVDD";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
- };
- };
-
- fragment@1 {
target = <&i2c>;
__overlay__ {
@@ -30,19 +17,19 @@
compatible = "adi,adau1977";
reg = <0x11>;
reset-gpios = <&gpio 5 0>;
- AVDD-supply = <&codec_supply>;
+ AVDD-supply = <&vdd_3v3_reg>;
};
};
};
- fragment@2 {
+ fragment@1 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
- fragment@3 {
+ fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "adi,adau1977-adc";
--- a/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts
+++ b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts
@@ -23,6 +23,9 @@
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4c>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
@@ -34,6 +34,9 @@
compatible = "ti,pcm5122";
reg = <0x4d>;
clocks = <&dacpro_osc>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts
+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts
@@ -23,6 +23,8 @@
#sound-dai-cells = <0>;
compatible = "wlf,wm8804";
reg = <0x3b>;
+ PVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
@@ -23,6 +23,8 @@
#sound-dai-cells = <0>;
compatible = "wlf,wm8804";
reg = <0x3b>;
+ PVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts
+++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts
@@ -23,6 +23,9 @@
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4c>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts
+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts
@@ -23,6 +23,9 @@
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4c>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts
+++ b/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts
@@ -24,8 +24,8 @@
compatible = "wlf,wm8804";
reg = <0x3b>;
status = "okay";
- // DVDD-supply = <&reg_3v3>;
- // PVDD-supply = <&reg_3v3>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ PVDD-supply = <&vdd_3v3_reg>;
};
};
};
--- a/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts
+++ b/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts
@@ -23,6 +23,9 @@
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4d>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts
+++ b/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts
@@ -23,6 +23,8 @@
#sound-dai-cells = <0>;
compatible = "wlf,wm8804";
reg = <0x3b>;
+ PVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts
+++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts
@@ -23,12 +23,16 @@
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4c>;
+ AVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
tpa6130a2: tpa6130a2@60 {
compatible = "ti,tpa6130a2";
reg = <0x60>;
+ Vdd-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
--- a/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts
+++ b/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts
@@ -6,45 +6,13 @@
compatible = "brcm,bcm2708";
fragment@0 {
- target-path = "/";
- __overlay__ {
- aliases {
- ldo0 = &ldo0;
- ldo1 = &ldo1;
- };
- };
- };
-
- fragment@1 {
- target-path = "/soc";
- __overlay__ {
-
- ldo1: ldo1 {
- compatible = "regulator-fixed";
- regulator-name = "DC_5V";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-always-on;
- };
-
- ldo0: ldo0 {
- compatible = "regulator-fixed";
- regulator-name = "DC_3V3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
- };
- };
-
- fragment@2 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
- fragment@3 {
+ fragment@1 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
@@ -56,21 +24,21 @@
compatible = "wlf,wm8804";
reg = <0x3b>;
status = "okay";
- PVDD-supply = <&ldo0>;
- DVDD-supply = <&ldo0>;
+ PVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
};
wm8742: wm8741@1a {
compatible = "wlf,wm8741";
reg = <0x1a>;
status = "okay";
- AVDD-supply = <&ldo1>;
- DVDD-supply = <&ldo0>;
+ AVDD-supply = <&vdd_5v0_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
};
};
};
- fragment@4 {
+ fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "rra,digidac1-soundcard";

@ -0,0 +1,1238 @@
From 8729879667d0668f20bd2aba8473879ac1d0216d Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:37 +0100
Subject: [PATCH] ASoC: Add driver for Cirrus Logic Audio Card
Note: due to problems with deferred probing of regulators
the following softdep should be added to a modprobe.d file
softdep arizona-spi pre: arizona-ldo1
Signed-off-by: Matthias Reichl <hias@horus.com>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 6 +
.../dts/overlays/rpi-cirrus-wm5102-overlay.dts | 146 +++
sound/soc/bcm/Kconfig | 9 +
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/rpi-cirrus.c | 1003 ++++++++++++++++++++
6 files changed, 1167 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts
create mode 100644 sound/soc/bcm/rpi-cirrus.c
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -68,6 +68,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
qca7000.dtbo \
raspidac3.dtbo \
rpi-backlight.dtbo \
+ rpi-cirrus-wm5102.dtbo \
rpi-dac.dtbo \
rpi-display.dtbo \
rpi-ft5406.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -995,6 +995,12 @@ Load: dtoverlay=rpi-backlight
Params: <None>
+Name: rpi-cirrus-wm5102
+Info: Configures the Cirrus Logic Audio Card
+Load: dtoverlay=rpi-cirrus-wm5102
+Params: <None>
+
+
Name: rpi-dac
Info: Configures the RPi DAC audio card
Load: dtoverlay=rpi-dac
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts
@@ -0,0 +1,146 @@
+// Definitions for the Cirrus Logic Audio Card
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/arizona.h>
+
+/ {
+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ wlf_pins: wlf_pins {
+ brcm,pins = <17 22 27 8>;
+ brcm,function = <
+ BCM2835_FSEL_GPIO_OUT
+ BCM2835_FSEL_GPIO_OUT
+ BCM2835_FSEL_GPIO_IN
+ BCM2835_FSEL_GPIO_OUT
+ >;
+ };
+ };
+ };
+
+ fragment@2 {
+ target-path = "/";
+ __overlay__ {
+ rpi_cirrus_reg_1v8: rpi_cirrus_reg_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "RPi-Cirrus 1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ fragment@3 {
+ target = <&spi0>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ spidev@0{
+ status = "disabled";
+ };
+
+ spidev@1{
+ status = "disabled";
+ };
+
+ wm5102@1{
+ compatible = "wlf,wm5102";
+ reg = <1>;
+
+ spi-max-frequency = <500000>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <27 8>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ LDOVDD-supply = <&rpi_cirrus_reg_1v8>;
+ AVDD-supply = <&rpi_cirrus_reg_1v8>;
+ DBVDD1-supply = <&rpi_cirrus_reg_1v8>;
+ DBVDD2-supply = <&vdd_3v3_reg>;
+ DBVDD3-supply = <&vdd_3v3_reg>;
+ CPVDD-supply = <&rpi_cirrus_reg_1v8>;
+ SPKVDDL-supply = <&vdd_5v0_reg>;
+ SPKVDDR-supply = <&vdd_5v0_reg>;
+ DCVDD-supply = <&arizona_ldo1>;
+
+ wlf,reset = <&gpio 17 GPIO_ACTIVE_HIGH>;
+ wlf,ldoena = <&gpio 22 GPIO_ACTIVE_HIGH>;
+ wlf,gpio-defaults = <
+ ARIZONA_GP_DEFAULT
+ ARIZONA_GP_DEFAULT
+ ARIZONA_GP_DEFAULT
+ ARIZONA_GP_DEFAULT
+ ARIZONA_GP_DEFAULT
+ >;
+ wlf,micd-configs = <0 1 0>;
+ wlf,dmic-ref = <
+ ARIZONA_DMIC_MICVDD
+ ARIZONA_DMIC_MICBIAS2
+ ARIZONA_DMIC_MICVDD
+ ARIZONA_DMIC_MICVDD
+ >;
+ wlf,inmode = <
+ ARIZONA_INMODE_DIFF
+ ARIZONA_INMODE_DMIC
+ ARIZONA_INMODE_SE
+ ARIZONA_INMODE_DIFF
+ >;
+ status = "okay";
+
+ arizona_ldo1: ldo1 {
+ regulator-name = "LDO1";
+ // default constraints as in
+ // arizona-ldo1.c
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ fragment@4 {
+ target = <&i2c1>;
+ __overlay__ {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wm8804@3b {
+ compatible = "wlf,wm8804";
+ reg = <0x3b>;
+ status = "okay";
+ PVDD-supply = <&vdd_3v3_reg>;
+ DVDD-supply = <&vdd_3v3_reg>;
+ wlf,reset-gpio = <&gpio 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ };
+
+ fragment@5 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "wlf,rpi-cirrus";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+};
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -45,6 +45,15 @@ config SND_BCM2708_SOC_HIFIBERRY_AMP
help
Say Y or M if you want to add support for the HifiBerry Amp amplifier board.
+config SND_BCM2708_SOC_RPI_CIRRUS
+ tristate "Support for Cirrus Logic Audio Card"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+ select SND_SOC_WM5102
+ select SND_SOC_WM8804
+ help
+ Say Y or M if you want to add support for the Wolfson and
+ Cirrus Logic audio cards.
+
config SND_BCM2708_SOC_RPI_DAC
tristate "Support for RPi-DAC"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -16,6 +16,7 @@ snd-soc-hifiberry-dacplus-objs := hifibe
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
snd-soc-justboom-dac-objs := justboom-dac.o
snd-soc-justboom-digi-objs := justboom-digi.o
+snd-soc-rpi-cirrus-objs := rpi-cirrus.o
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI) += snd-soc-justboom-digi.o
+obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
--- /dev/null
+++ b/sound/soc/bcm/rpi-cirrus.c
@@ -0,0 +1,1003 @@
+/*
+ * ASoC machine driver for Cirrus Logic Audio Card
+ * (with WM5102 and WM8804 codecs)
+ *
+ * Copyright 2015-2017 Matthias Reichl <hias@horus.com>
+ *
+ * Based on rpi-cirrus-sound-pi driver (c) Wolfson / Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <sound/pcm_params.h>
+
+#include <linux/mfd/arizona/registers.h>
+
+#include "../codecs/wm5102.h"
+#include "../codecs/wm8804.h"
+
+#define WM8804_CLKOUT_HZ 12000000
+
+#define RPI_CIRRUS_DEFAULT_RATE 44100
+#define WM5102_MAX_SYSCLK_1 49152000 /* max sysclk for 4K family */
+#define WM5102_MAX_SYSCLK_2 45158400 /* max sysclk for 11.025K family */
+
+static inline unsigned int calc_sysclk(unsigned int rate)
+{
+ return (rate % 4000) ? WM5102_MAX_SYSCLK_2 : WM5102_MAX_SYSCLK_1;
+}
+
+enum {
+ DAI_WM5102 = 0,
+ DAI_WM8804,
+};
+
+struct rpi_cirrus_priv {
+ /* mutex for synchronzing FLL1 access with DAPM */
+ struct mutex lock;
+ unsigned int card_rate;
+ int sync_path_enable;
+ int fll1_freq; /* negative means RefClock in spdif rx case */
+
+ /* track hw params/free for substreams */
+ unsigned int params_set;
+ unsigned int min_rate_idx, max_rate_idx;
+ unsigned char iec958_status[4];
+};
+
+/* helper functions */
+static inline struct snd_soc_pcm_runtime *get_wm5102_runtime(
+ struct snd_soc_card *card) {
+ return snd_soc_get_pcm_runtime(card, card->dai_link[DAI_WM5102].name);
+}
+
+static inline struct snd_soc_pcm_runtime *get_wm8804_runtime(
+ struct snd_soc_card *card) {
+ return snd_soc_get_pcm_runtime(card, card->dai_link[DAI_WM8804].name);
+}
+
+
+struct rate_info {
+ unsigned int value;
+ char *text;
+};
+
+static struct rate_info min_rates[] = {
+ { 0, "off"},
+ { 32000, "32kHz"},
+ { 44100, "44.1kHz"}
+};
+
+#define NUM_MIN_RATES ARRAY_SIZE(min_rates)
+
+static int rpi_cirrus_min_rate_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = NUM_MIN_RATES;
+
+ if (uinfo->value.enumerated.item >= NUM_MIN_RATES)
+ uinfo->value.enumerated.item = NUM_MIN_RATES - 1;
+ strcpy(uinfo->value.enumerated.name,
+ min_rates[uinfo->value.enumerated.item].text);
+ return 0;
+}
+
+static int rpi_cirrus_min_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+
+ ucontrol->value.enumerated.item[0] = priv->min_rate_idx;
+ return 0;
+}
+
+static int rpi_cirrus_min_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ int changed = 0;
+
+ if (priv->min_rate_idx != ucontrol->value.enumerated.item[0]) {
+ changed = 1;
+ priv->min_rate_idx = ucontrol->value.enumerated.item[0];
+ }
+
+ return changed;
+}
+
+static struct rate_info max_rates[] = {
+ { 0, "off"},
+ { 48000, "48kHz"},
+ { 96000, "96kHz"}
+};
+
+#define NUM_MAX_RATES ARRAY_SIZE(max_rates)
+
+static int rpi_cirrus_max_rate_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = NUM_MAX_RATES;
+ if (uinfo->value.enumerated.item >= NUM_MAX_RATES)
+ uinfo->value.enumerated.item = NUM_MAX_RATES - 1;
+ strcpy(uinfo->value.enumerated.name,
+ max_rates[uinfo->value.enumerated.item].text);
+ return 0;
+}
+
+static int rpi_cirrus_max_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+
+ ucontrol->value.enumerated.item[0] = priv->max_rate_idx;
+ return 0;
+}
+
+static int rpi_cirrus_max_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ int changed = 0;
+
+ if (priv->max_rate_idx != ucontrol->value.enumerated.item[0]) {
+ changed = 1;
+ priv->max_rate_idx = ucontrol->value.enumerated.item[0];
+ }
+
+ return changed;
+}
+
+static int rpi_cirrus_spdif_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int rpi_cirrus_spdif_playback_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ int i;
+
+ for (i = 0; i < 4; i++)
+ ucontrol->value.iec958.status[i] = priv->iec958_status[i];
+
+ return 0;
+}
+
+static int rpi_cirrus_spdif_playback_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *wm8804_codec = get_wm8804_runtime(card)->codec;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ unsigned char *stat = priv->iec958_status;
+ unsigned char *ctrl_stat = ucontrol->value.iec958.status;
+ unsigned int mask;
+ int i, changed = 0;
+
+ for (i = 0; i < 4; i++) {
+ mask = (i == 3) ? 0x3f : 0xff;
+ if ((ctrl_stat[i] & mask) != (stat[i] & mask)) {
+ changed = 1;
+ stat[i] = ctrl_stat[i] & mask;
+ snd_soc_update_bits(wm8804_codec,
+ WM8804_SPDTX1 + i, mask, stat[i]);
+ }
+ }
+
+ return changed;
+}
+
+static int rpi_cirrus_spdif_mask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.iec958.status[0] = 0xff;
+ ucontrol->value.iec958.status[1] = 0xff;
+ ucontrol->value.iec958.status[2] = 0xff;
+ ucontrol->value.iec958.status[3] = 0x3f;
+
+ return 0;
+}
+
+static int rpi_cirrus_spdif_capture_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *wm8804_codec = get_wm8804_runtime(card)->codec;
+ unsigned int mask;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ mask = (i == 3) ? 0x3f : 0xff;
+ ucontrol->value.iec958.status[i] =
+ snd_soc_read(wm8804_codec, WM8804_RXCHAN1 + i) & mask;
+ }
+
+ return 0;
+}
+
+#define SPDIF_FLAG_CTRL(desc, reg, bit, invert) \
+{ \
+ .access = SNDRV_CTL_ELEM_ACCESS_READ \
+ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) \
+ desc " Flag", \
+ .info = snd_ctl_boolean_mono_info, \
+ .get = rpi_cirrus_spdif_status_flag_get, \
+ .private_value = \
+ (bit) | ((reg) << 8) | ((invert) << 16) \
+}
+
+static int rpi_cirrus_spdif_status_flag_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *wm8804_codec = get_wm8804_runtime(card)->codec;
+
+ unsigned int bit = kcontrol->private_value & 0xff;
+ unsigned int reg = (kcontrol->private_value >> 8) & 0xff;
+ unsigned int invert = (kcontrol->private_value >> 16) & 0xff;
+
+ bool flag = snd_soc_read(wm8804_codec, reg) & (1 << bit);
+
+ ucontrol->value.integer.value[0] = invert ? !flag : flag;
+
+ return 0;
+}
+
+static const char * const recovered_frequency_texts[] = {
+ "176.4/192 kHz",
+ "88.2/96 kHz",
+ "44.1/48 kHz",
+ "32 kHz"
+};
+
+#define NUM_RECOVERED_FREQUENCIES \
+ ARRAY_SIZE(recovered_frequency_texts)
+
+static int rpi_cirrus_recovered_frequency_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = NUM_RECOVERED_FREQUENCIES;
+ if (uinfo->value.enumerated.item >= NUM_RECOVERED_FREQUENCIES)
+ uinfo->value.enumerated.item = NUM_RECOVERED_FREQUENCIES - 1;
+ strcpy(uinfo->value.enumerated.name,
+ recovered_frequency_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+static int rpi_cirrus_recovered_frequency_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *wm8804_codec = get_wm8804_runtime(card)->codec;
+
+ ucontrol->value.enumerated.item[0] =
+ (snd_soc_read(wm8804_codec, WM8804_SPDSTAT) >> 4) & 0x03;
+ return 0;
+}
+
+static const struct snd_kcontrol_new rpi_cirrus_controls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Min Sample Rate",
+ .info = rpi_cirrus_min_rate_info,
+ .get = rpi_cirrus_min_rate_get,
+ .put = rpi_cirrus_min_rate_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Max Sample Rate",
+ .info = rpi_cirrus_max_rate_info,
+ .get = rpi_cirrus_max_rate_get,
+ .put = rpi_cirrus_max_rate_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .info = rpi_cirrus_spdif_info,
+ .get = rpi_cirrus_spdif_playback_get,
+ .put = rpi_cirrus_spdif_playback_put,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ
+ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
+ .info = rpi_cirrus_spdif_info,
+ .get = rpi_cirrus_spdif_capture_get,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
+ .info = rpi_cirrus_spdif_info,
+ .get = rpi_cirrus_spdif_mask_get,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ
+ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE)
+ "Recovered Frequency",
+ .info = rpi_cirrus_recovered_frequency_info,
+ .get = rpi_cirrus_recovered_frequency_get,
+ },
+ SPDIF_FLAG_CTRL("Audio", WM8804_SPDSTAT, 0, 1),
+ SPDIF_FLAG_CTRL("Non-PCM", WM8804_SPDSTAT, 1, 0),
+ SPDIF_FLAG_CTRL("Copyright", WM8804_SPDSTAT, 2, 1),
+ SPDIF_FLAG_CTRL("De-Emphasis", WM8804_SPDSTAT, 3, 0),
+ SPDIF_FLAG_CTRL("Lock", WM8804_SPDSTAT, 6, 1),
+ SPDIF_FLAG_CTRL("Invalid", WM8804_INTSTAT, 1, 0),
+ SPDIF_FLAG_CTRL("TransErr", WM8804_INTSTAT, 3, 0),
+};
+
+static const char * const linein_micbias_texts[] = {
+ "off", "on",
+};
+
+static SOC_ENUM_SINGLE_VIRT_DECL(linein_micbias_enum,
+ linein_micbias_texts);
+
+static const struct snd_kcontrol_new linein_micbias_mux =
+ SOC_DAPM_ENUM("Route", linein_micbias_enum);
+
+static int rpi_cirrus_spdif_rx_enable_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+
+const struct snd_soc_dapm_widget rpi_cirrus_dapm_widgets[] = {
+ SND_SOC_DAPM_MIC("DMIC", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_INPUT("Line Input"),
+ SND_SOC_DAPM_MIC("Line Input with Micbias", NULL),
+ SND_SOC_DAPM_MUX("Line Input Micbias", SND_SOC_NOPM, 0, 0,
+ &linein_micbias_mux),
+ SND_SOC_DAPM_INPUT("dummy SPDIF in"),
+ SND_SOC_DAPM_PGA_E("dummy SPDIFRX", SND_SOC_NOPM, 0, 0, NULL, 0,
+ rpi_cirrus_spdif_rx_enable_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_INPUT("Dummy Input"),
+ SND_SOC_DAPM_OUTPUT("Dummy Output"),
+};
+
+const struct snd_soc_dapm_route rpi_cirrus_dapm_routes[] = {
+ { "IN1L", NULL, "Headset Mic" },
+ { "IN1R", NULL, "Headset Mic" },
+ { "Headset Mic", NULL, "MICBIAS1" },
+
+ { "IN2L", NULL, "DMIC" },
+ { "IN2R", NULL, "DMIC" },
+ { "DMIC", NULL, "MICBIAS2" },
+
+ { "IN3L", NULL, "Line Input Micbias" },
+ { "IN3R", NULL, "Line Input Micbias" },
+
+ { "Line Input Micbias", "off", "Line Input" },
+ { "Line Input Micbias", "on", "Line Input with Micbias" },
+
+ /* Make sure MICVDD is enabled, otherwise we get noise */
+ { "Line Input", NULL, "MICVDD" },
+ { "Line Input with Micbias", NULL, "MICBIAS3" },
+
+ /* Dummy routes to check whether SPDIF RX is enabled or not */
+ {"dummy SPDIFRX", NULL, "dummy SPDIF in"},
+ {"AIFTX", NULL, "dummy SPDIFRX"},
+
+ /*
+ * Dummy routes to keep wm5102 from staying off on
+ * playback/capture if all mixers are off.
+ */
+ { "Dummy Output", NULL, "AIF1RX1" },
+ { "Dummy Output", NULL, "AIF1RX2" },
+ { "AIF1TX1", NULL, "Dummy Input" },
+ { "AIF1TX2", NULL, "Dummy Input" },
+};
+
+static int rpi_cirrus_clear_flls(struct snd_soc_card *card,
+ struct snd_soc_codec *wm5102_codec) {
+
+ int ret1, ret2;
+
+ ret1 = snd_soc_codec_set_pll(wm5102_codec,
+ WM5102_FLL1, ARIZONA_FLL_SRC_NONE, 0, 0);
+ ret2 = snd_soc_codec_set_pll(wm5102_codec,
+ WM5102_FLL1_REFCLK, ARIZONA_FLL_SRC_NONE, 0, 0);
+
+ if (ret1) {
+ dev_warn(card->dev,
+ "setting FLL1 to zero failed: %d\n", ret1);
+ return ret1;
+ }
+ if (ret2) {
+ dev_warn(card->dev,
+ "setting FLL1_REFCLK to zero failed: %d\n", ret2);
+ return ret2;
+ }
+ return 0;
+}
+
+static int rpi_cirrus_set_fll(struct snd_soc_card *card,
+ struct snd_soc_codec *wm5102_codec, unsigned int clk_freq)
+{
+ int ret = snd_soc_codec_set_pll(wm5102_codec,
+ WM5102_FLL1,
+ ARIZONA_CLK_SRC_MCLK1,
+ WM8804_CLKOUT_HZ,
+ clk_freq);
+ if (ret)
+ dev_err(card->dev, "Failed to set FLL1 to %d: %d\n",
+ clk_freq, ret);
+
+ usleep_range(1000, 2000);
+ return ret;
+}
+
+static int rpi_cirrus_set_fll_refclk(struct snd_soc_card *card,
+ struct snd_soc_codec *wm5102_codec,
+ unsigned int clk_freq, unsigned int aif2_freq)
+{
+ int ret = snd_soc_codec_set_pll(wm5102_codec,
+ WM5102_FLL1_REFCLK,
+ ARIZONA_CLK_SRC_MCLK1,
+ WM8804_CLKOUT_HZ,
+ clk_freq);
+ if (ret) {
+ dev_err(card->dev,
+ "Failed to set FLL1_REFCLK to %d: %d\n",
+ clk_freq, ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_pll(wm5102_codec,
+ WM5102_FLL1,
+ ARIZONA_CLK_SRC_AIF2BCLK,
+ aif2_freq, clk_freq);
+ if (ret)
+ dev_err(card->dev,
+ "Failed to set FLL1 with Sync Clock %d to %d: %d\n",
+ aif2_freq, clk_freq, ret);
+
+ usleep_range(1000, 2000);
+ return ret;
+}
+
+static int rpi_cirrus_spdif_rx_enable_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_card *card = w->dapm->card;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_codec *wm5102_codec = get_wm5102_runtime(card)->codec;
+
+ unsigned int clk_freq, aif2_freq;
+ int ret = 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ mutex_lock(&priv->lock);
+
+ /* Enable sync path in case of SPDIF capture use case */
+
+ clk_freq = calc_sysclk(priv->card_rate);
+ aif2_freq = 64 * priv->card_rate;
+
+ dev_dbg(card->dev,
+ "spdif_rx: changing FLL1 to use Ref Clock clk: %d spdif: %d\n",
+ clk_freq, aif2_freq);
+
+ ret = rpi_cirrus_clear_flls(card, wm5102_codec);
+ if (ret) {
+ dev_err(card->dev, "spdif_rx: failed to clear FLLs\n");
+ goto out;
+ }
+
+ ret = rpi_cirrus_set_fll_refclk(card, wm5102_codec,
+ clk_freq, aif2_freq);
+
+ if (ret) {
+ dev_err(card->dev, "spdif_rx: failed to set FLLs\n");
+ goto out;
+ }
+
+ /* set to negative to indicate we're doing spdif rx */
+ priv->fll1_freq = -clk_freq;
+ priv->sync_path_enable = 1;
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ mutex_lock(&priv->lock);
+ priv->sync_path_enable = 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+out:
+ mutex_unlock(&priv->lock);
+ return ret;
+}
+
+static int rpi_cirrus_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_pcm_runtime *wm5102_runtime = get_wm5102_runtime(card);
+ struct snd_soc_codec *wm5102_codec = wm5102_runtime->codec;
+
+ int ret = 0;
+ unsigned int clk_freq;
+
+ if (dapm->dev != wm5102_runtime->codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (dapm->bias_level == SND_SOC_BIAS_ON)
+ break;
+
+ mutex_lock(&priv->lock);
+
+ if (!priv->sync_path_enable) {
+ clk_freq = calc_sysclk(priv->card_rate);
+
+ dev_dbg(card->dev,
+ "set_bias: changing FLL1 from %d to %d\n",
+ priv->fll1_freq, clk_freq);
+
+ ret = rpi_cirrus_set_fll(card, wm5102_codec, clk_freq);
+ if (ret)
+ dev_err(card->dev,
+ "set_bias: Failed to set FLL1\n");
+ else
+ priv->fll1_freq = clk_freq;
+ }
+ mutex_unlock(&priv->lock);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int rpi_cirrus_set_bias_level_post(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_pcm_runtime *wm5102_runtime = get_wm5102_runtime(card);
+ struct snd_soc_codec *wm5102_codec = wm5102_runtime->codec;
+
+ if (dapm->dev != wm5102_runtime->codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ mutex_lock(&priv->lock);
+
+ dev_dbg(card->dev,
+ "set_bias_post: changing FLL1 from %d to off\n",
+ priv->fll1_freq);
+
+ if (rpi_cirrus_clear_flls(card, wm5102_codec))
+ dev_err(card->dev,
+ "set_bias_post: failed to clear FLLs\n");
+ else
+ priv->fll1_freq = 0;
+
+ mutex_unlock(&priv->lock);
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int rpi_cirrus_set_wm8804_pll(struct snd_soc_card *card,
+ struct snd_soc_dai *wm8804_dai, unsigned int rate)
+{
+ int ret;
+
+ /* use 256fs */
+ unsigned int clk_freq = rate * 256;
+
+ ret = snd_soc_dai_set_pll(wm8804_dai, 0, 0,
+ WM8804_CLKOUT_HZ, clk_freq);
+ if (ret) {
+ dev_err(card->dev,
+ "Failed to set WM8804 PLL to %d: %d\n", clk_freq, ret);
+ return ret;
+ }
+
+ /* Set MCLK as PLL Output */
+ ret = snd_soc_dai_set_sysclk(wm8804_dai,
+ WM8804_TX_CLKSRC_PLL, clk_freq, 0);
+ if (ret) {
+ dev_err(card->dev,
+ "Failed to set MCLK as PLL Output: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int rpi_cirrus_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ unsigned int min_rate = min_rates[priv->min_rate_idx].value;
+ unsigned int max_rate = max_rates[priv->max_rate_idx].value;
+
+ if (min_rate || max_rate) {
+ if (max_rate == 0)
+ max_rate = UINT_MAX;
+
+ dev_dbg(card->dev,
+ "startup: limiting rate to %u-%u\n",
+ min_rate, max_rate);
+
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE, min_rate, max_rate);
+ }
+
+ return 0;
+}
+
+static struct snd_soc_pcm_stream rpi_cirrus_dai_link2_params = {
+ .formats = SNDRV_PCM_FMTBIT_S24_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = RPI_CIRRUS_DEFAULT_RATE,
+ .rate_max = RPI_CIRRUS_DEFAULT_RATE,
+};
+
+static int rpi_cirrus_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *bcm_i2s_dai = rtd->cpu_dai;
+ struct snd_soc_codec *wm5102_codec = rtd->codec;
+ struct snd_soc_dai *wm8804_dai = get_wm8804_runtime(card)->codec_dai;
+
+ int ret;
+
+ unsigned int width = snd_pcm_format_physical_width(
+ params_format(params));
+ unsigned int rate = params_rate(params);
+ unsigned int clk_freq = calc_sysclk(rate);
+
+ mutex_lock(&priv->lock);
+
+ dev_dbg(card->dev, "hw_params: setting rate to %d\n", rate);
+
+ ret = snd_soc_dai_set_bclk_ratio(bcm_i2s_dai, 2 * width);
+ if (ret) {
+ dev_err(card->dev, "set_bclk_ratio failed: %d\n", ret);
+ goto out;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0x03, 0x03, 2, width);
+ if (ret) {
+ dev_err(card->dev, "set_tdm_slot failed: %d\n", ret);
+ goto out;
+ }
+
+ /* WM8804 supports sample rates from 32k only */
+ if (rate >= 32000) {
+ ret = rpi_cirrus_set_wm8804_pll(card, wm8804_dai, rate);
+ if (ret)
+ goto out;
+ }
+
+ ret = snd_soc_codec_set_sysclk(wm5102_codec,
+ ARIZONA_CLK_SYSCLK,
+ ARIZONA_CLK_SRC_FLL1,
+ clk_freq,
+ SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(card->dev, "Failed to set SYSCLK: %d\n", ret);
+ goto out;
+ }
+
+ if ((priv->fll1_freq > 0) && (priv->fll1_freq != clk_freq)) {
+ dev_dbg(card->dev,
+ "hw_params: changing FLL1 from %d to %d\n",
+ priv->fll1_freq, clk_freq);
+
+ if (rpi_cirrus_clear_flls(card, wm5102_codec)) {
+ dev_err(card->dev, "hw_params: failed to clear FLLs\n");
+ goto out;
+ }
+
+ if (rpi_cirrus_set_fll(card, wm5102_codec, clk_freq)) {
+ dev_err(card->dev, "hw_params: failed to set FLL\n");
+ goto out;
+ }
+
+ priv->fll1_freq = clk_freq;
+ }
+
+ priv->card_rate = rate;
+ rpi_cirrus_dai_link2_params.rate_min = rate;
+ rpi_cirrus_dai_link2_params.rate_max = rate;
+
+ priv->params_set |= 1 << substream->stream;
+
+out:
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
+static int rpi_cirrus_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_codec *wm5102_codec = rtd->codec;
+ int ret;
+ unsigned int old_params_set = priv->params_set;
+
+ priv->params_set &= ~(1 << substream->stream);
+
+ /* disable sysclk if this was the last open stream */
+ if (priv->params_set == 0 && old_params_set) {
+ dev_dbg(card->dev,
+ "hw_free: Setting SYSCLK to Zero\n");
+
+ ret = snd_soc_codec_set_sysclk(wm5102_codec,
+ ARIZONA_CLK_SYSCLK,
+ ARIZONA_CLK_SRC_FLL1,
+ 0,
+ SND_SOC_CLOCK_IN);
+ if (ret)
+ dev_err(card->dev,
+ "hw_free: Failed to set SYSCLK to Zero: %d\n",
+ ret);
+ }
+ return 0;
+}
+
+static int rpi_cirrus_init_wm5102(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret;
+
+ /* no 32kHz input, derive it from sysclk if needed */
+ snd_soc_update_bits(codec,
+ ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2);
+
+ if (rpi_cirrus_clear_flls(rtd->card, codec))
+ dev_warn(rtd->card->dev,
+ "init_wm5102: failed to clear FLLs\n");
+
+ ret = snd_soc_codec_set_sysclk(codec,
+ ARIZONA_CLK_SYSCLK, ARIZONA_CLK_SRC_FLL1,
+ 0, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(rtd->card->dev,
+ "Failed to set SYSCLK to Zero: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rpi_cirrus_init_wm8804(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ unsigned int mask;
+ int i, ret;
+
+ for (i = 0; i < 4; i++) {
+ mask = (i == 3) ? 0x3f : 0xff;
+ priv->iec958_status[i] =
+ snd_soc_read(codec, WM8804_SPDTX1 + i) & mask;
+ }
+
+ /* Setup for 256fs */
+ ret = snd_soc_dai_set_clkdiv(codec_dai,
+ WM8804_MCLK_DIV, WM8804_MCLKDIV_256FS);
+ if (ret) {
+ dev_err(card->dev,
+ "init_wm8804: Failed to set MCLK_DIV to 256fs: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Output OSC on CLKOUT */
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ WM8804_CLKOUT_SRC_OSCCLK, WM8804_CLKOUT_HZ, 0);
+ if (ret)
+ dev_err(card->dev,
+ "init_wm8804: Failed to set CLKOUT as OSC Frequency: %d\n",
+ ret);
+
+ /* Init PLL with default samplerate */
+ ret = rpi_cirrus_set_wm8804_pll(card, codec_dai,
+ RPI_CIRRUS_DEFAULT_RATE);
+ if (ret)
+ dev_err(card->dev,
+ "init_wm8804: Failed to setup PLL for %dHz: %d\n",
+ RPI_CIRRUS_DEFAULT_RATE, ret);
+
+ return ret;
+}
+
+static struct snd_soc_ops rpi_cirrus_ops = {
+ .startup = rpi_cirrus_startup,
+ .hw_params = rpi_cirrus_hw_params,
+ .hw_free = rpi_cirrus_hw_free,
+};
+
+static struct snd_soc_dai_link rpi_cirrus_dai[] = {
+ [DAI_WM5102] = {
+ .name = "WM5102",
+ .stream_name = "WM5102 AiFi",
+ .codec_dai_name = "wm5102-aif1",
+ .codec_name = "wm5102-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ .ops = &rpi_cirrus_ops,
+ .init = rpi_cirrus_init_wm5102,
+ },
+ [DAI_WM8804] = {
+ .name = "WM5102 SPDIF",
+ .stream_name = "SPDIF Tx/Rx",
+ .cpu_dai_name = "wm5102-aif2",
+ .codec_dai_name = "wm8804-spdif",
+ .codec_name = "wm8804.1-003b",
+ .dai_fmt = SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ .ignore_suspend = 1,
+ .params = &rpi_cirrus_dai_link2_params,
+ .init = rpi_cirrus_init_wm8804,
+ },
+};
+
+
+static int rpi_cirrus_late_probe(struct snd_soc_card *card)
+{
+ struct rpi_cirrus_priv *priv = snd_soc_card_get_drvdata(card);
+ struct snd_soc_pcm_runtime *wm5102_runtime = get_wm5102_runtime(card);
+ struct snd_soc_pcm_runtime *wm8804_runtime = get_wm8804_runtime(card);
+ int ret;
+
+ dev_dbg(card->dev, "iec958_bits: %02x %02x %02x %02x\n",
+ priv->iec958_status[0],
+ priv->iec958_status[1],
+ priv->iec958_status[2],
+ priv->iec958_status[3]);
+
+ ret = snd_soc_dai_set_sysclk(
+ wm5102_runtime->codec_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+ if (ret) {
+ dev_err(card->dev,
+ "Failed to set WM5102 codec dai clk domain: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(
+ wm8804_runtime->cpu_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+ if (ret)
+ dev_err(card->dev,
+ "Failed to set WM8804 codec dai clk domain: %d\n", ret);
+
+ return ret;
+}
+
+/* audio machine driver */
+static struct snd_soc_card rpi_cirrus_card = {
+ .name = "RPi-Cirrus",
+ .driver_name = "RPiCirrus",
+ .owner = THIS_MODULE,
+ .dai_link = rpi_cirrus_dai,
+ .num_links = ARRAY_SIZE(rpi_cirrus_dai),
+ .late_probe = rpi_cirrus_late_probe,
+ .controls = rpi_cirrus_controls,
+ .num_controls = ARRAY_SIZE(rpi_cirrus_controls),
+ .dapm_widgets = rpi_cirrus_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rpi_cirrus_dapm_widgets),
+ .dapm_routes = rpi_cirrus_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(rpi_cirrus_dapm_routes),
+ .set_bias_level = rpi_cirrus_set_bias_level,
+ .set_bias_level_post = rpi_cirrus_set_bias_level_post,
+};
+
+static int rpi_cirrus_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct rpi_cirrus_priv *priv;
+ struct device_node *i2s_node;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->min_rate_idx = 1; /* min samplerate 32kHz */
+ priv->card_rate = RPI_CIRRUS_DEFAULT_RATE;
+
+ mutex_init(&priv->lock);
+
+ snd_soc_card_set_drvdata(&rpi_cirrus_card, priv);
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ i2s_node = of_parse_phandle(
+ pdev->dev.of_node, "i2s-controller", 0);
+ if (!i2s_node) {
+ dev_err(&pdev->dev, "i2s-controller missing in DT\n");
+ return -ENODEV;
+ }
+
+ rpi_cirrus_dai[DAI_WM5102].cpu_of_node = i2s_node;
+ rpi_cirrus_dai[DAI_WM5102].platform_of_node = i2s_node;
+
+ rpi_cirrus_card.dev = &pdev->dev;
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &rpi_cirrus_card);
+ if (ret) {
+ if (ret == -EPROBE_DEFER)
+ dev_dbg(&pdev->dev,
+ "register card requested probe deferral\n");
+ else
+ dev_err(&pdev->dev,
+ "Failed to register card: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static const struct of_device_id rpi_cirrus_of_match[] = {
+ { .compatible = "wlf,rpi-cirrus", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rpi_cirrus_of_match);
+
+static struct platform_driver rpi_cirrus_driver = {
+ .driver = {
+ .name = "snd-rpi-cirrus",
+ .of_match_table = of_match_ptr(rpi_cirrus_of_match),
+ },
+ .probe = rpi_cirrus_probe,
+};
+
+module_platform_driver(rpi_cirrus_driver);
+
+MODULE_AUTHOR("Matthias Reichl <hias@horus.com>");
+MODULE_DESCRIPTION("ASoC driver for Cirrus Logic Audio Card");
+MODULE_LICENSE("GPL");

@ -0,0 +1,47 @@
From e12d55ad45094a50ff25b70d76381bc7798ea3d5 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:37 +0100
Subject: [PATCH] config: enable Cirrus Logic Audio Card
Signed-off-by: Matthias Reichl <hias@horus.com>
---
arch/arm/configs/bcm2709_defconfig | 2 ++
arch/arm/configs/bcmrpi_defconfig | 2 ++
2 files changed, 4 insertions(+)
--- a/arch/arm/configs/bcm2709_defconfig
+++ b/arch/arm/configs/bcm2709_defconfig
@@ -666,6 +666,7 @@ CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_WM5102=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=m
+CONFIG_REGULATOR_ARIZONA=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
@@ -872,6 +873,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
+CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -660,6 +660,7 @@ CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_WM5102=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=m
+CONFIG_REGULATOR_ARIZONA=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
@@ -866,6 +867,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
+CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m

@ -0,0 +1,22 @@
From 6a2c90127ab305604fa51f30bce4f23179fa4b63 Mon Sep 17 00:00:00 2001
From: JamesH65 <JamesH65@users.noreply.github.com>
Date: Mon, 6 Feb 2017 15:24:47 +0000
Subject: [PATCH] gpio_mem: Remove unnecessary dev_info output (#1830)
The open function was spamming syslog every time
called, so have removed call completely.
---
drivers/char/broadcom/bcm2835-gpiomem.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/char/broadcom/bcm2835-gpiomem.c
+++ b/drivers/char/broadcom/bcm2835-gpiomem.c
@@ -76,8 +76,6 @@ static int bcm2835_gpiomem_open(struct i
int dev = iminor(inode);
int ret = 0;
- dev_info(inst->dev, "gpiomem device opened.");
-
if (dev != DEVICE_MINOR) {
dev_err(inst->dev, "Unknown minor device: %d", dev);
ret = -ENXIO;

@ -0,0 +1,10 @@
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -48,6 +48,7 @@ config SND_BCM2708_SOC_HIFIBERRY_AMP
config SND_BCM2708_SOC_RPI_CIRRUS
tristate "Support for Cirrus Logic Audio Card"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+ depends on BROKEN
select SND_SOC_WM5102
select SND_SOC_WM8804
help