一、Android禁止USB权限弹窗
当 Android 应用访问 USB 设备时,默认会弹出权限确认窗,这里修改 Framework 代码,默认授予 USB 权限而不弹窗。
禁止USB权限弹窗diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/framework
old mode 100644
new mode 100755
index 1e69fc5..815bb38
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -112,6 +112,10 @@ public class UsbPermissionActivity extends AlertActivitysetupAlert();+ // Add by shenhb@topband.com.cn, for cect7 disable USB permission popup.
+ mPermissionGranted = true;
+ finish();
+ // Add end}
二、4G模块开关机、复位、唤醒、休眠
4G 模块一般支持外部电路控制其开机、关机、复位、唤醒、休眠,为了实现通过 Java API 直接控制 4G 模块的这些动作,我们针对 4G 模块开发了专用驱动,同时增加了 Framework API。
修改
【4G】4G模块开关机、复位、唤醒、休眠diff --git a/device/rockchip/common/device.mk b/device/rockchip/common/device.mk
index 4df3ce6..aa65c72 100755
--- a/device/rockchip/common/device.mk
+++ b/device/rockchip/common/device.mk
@@ -364,7 +364,8 @@ PRODUCT_PACKAGES += \# Topband HALPRODUCT_PACKAGES += \gpio.default \
- mcu.default
+ mcu.default \
+ modem.default# iepifneq ($(filter rk3188 rk3190 rk3026 rk3288 rk312x rk3126c rk3128 px3se rk3368 rk3326 rk3328 rk3366 rk3399, $(strip $(TARGET_BOARD_PLATFORM))), )
diff --git a/frameworks/base/Android.mk b/frameworks/base/Android.mk
index af4872d..c6eaa5c 100755
--- a/frameworks/base/Android.mk
+++ b/frameworks/base/Android.mk
@@ -278,6 +278,7 @@ LOCAL_SRC_FILES += \core/java/android/os/IVibratorService.aidl \core/java/android/os/IGpioService.aidl \core/java/android/os/IMcuService.aidl \
+ core/java/android/os/IModemService.aidl \core/java/android/os/storage/IStorageManager.aidl \core/java/android/os/storage/IStorageEventListener.aidl \core/java/android/os/storage/IStorageShutdownObserver.aidl \
diff --git a/frameworks/base/api/current.txt b/frameworks/base/api/current.txt
index 5e3159f..2c23a3b 100644
--- a/frameworks/base/api/current.txt
+++ b/frameworks/base/api/current.txt
@@ -8974,6 +8974,7 @@ package android.content {field public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router";field public static final java.lang.String MEDIA_SESSION_SERVICE = "media_session";field public static final java.lang.String MIDI_SERVICE = "midi";
+ field public static final java.lang.String MODEM_SERVICE = "modem";field public static final int MODE_APPEND = 32768; // 0x8000field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8field public static final deprecated int MODE_MULTI_PROCESS = 4; // 0x4
diff --git a/frameworks/base/api/system-current.txt b/frameworks/base/api/system-current.txt
index 73aa112..3b671d8 100644
--- a/frameworks/base/api/system-current.txt
+++ b/frameworks/base/api/system-current.txt
@@ -9485,6 +9485,7 @@ package android.content {field public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router";field public static final java.lang.String MEDIA_SESSION_SERVICE = "media_session";field public static final java.lang.String MIDI_SERVICE = "midi";
+ field public static final java.lang.String MODEM_SERVICE = "modem";field public static final int MODE_APPEND = 32768; // 0x8000field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8field public static final deprecated int MODE_MULTI_PROCESS = 4; // 0x4
diff --git a/frameworks/base/api/test-current.txt b/frameworks/base/api/test-current.txt
index 6c1d4c6..20671d7 100644
--- a/frameworks/base/api/test-current.txt
+++ b/frameworks/base/api/test-current.txt
@@ -9008,6 +9008,7 @@ package android.content {field public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router";field public static final java.lang.String MEDIA_SESSION_SERVICE = "media_session";field public static final java.lang.String MIDI_SERVICE = "midi";
+ field public static final java.lang.String MODEM_SERVICE = "modem";field public static final int MODE_APPEND = 32768; // 0x8000field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8field public static final deprecated int MODE_MULTI_PROCESS = 4; // 0x4
diff --git a/frameworks/base/core/java/android/app/SystemServiceRegistry.java b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
index 8b609cf..5359b9b 100755
--- a/frameworks/base/core/java/android/app/SystemServiceRegistry.java
+++ b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
@@ -121,6 +121,7 @@ import android.os.UserManager;import android.os.Vibrator;import android.os.SystemGpio;import android.os.SystemMcu;
+import android.os.SystemModem;import android.os.health.SystemHealthManager;import android.os.storage.StorageManager;import android.print.IPrintManager;
@@ -552,6 +553,13 @@ final class SystemServiceRegistry {public SystemMcu createService(ContextImpl ctx) {return new SystemMcu(ctx);}});
+
+ registerService(Context.MODEM_SERVICE, SystemModem.class,
+ new CachedServiceFetcher<SystemModem>() {
+ @Override
+ public SystemModem createService(ContextImpl ctx) {
+ return new SystemModem(ctx);
+ }});registerService(Context.WALLPAPER_SERVICE, WallpaperManager.class,new CachedServiceFetcher<WallpaperManager>() {
diff --git a/frameworks/base/core/java/android/content/Context.java b/frameworks/base/core/java/android/content/Context.java
index 778bc98..a72cf37 100755
--- a/frameworks/base/core/java/android/content/Context.java
+++ b/frameworks/base/core/java/android/content/Context.java
@@ -3355,6 +3355,7 @@ public abstract class Context {public static final String GPIO_SERVICE = "gpio";public static final String MCU_SERVICE = "mcu";
+ public static final String MODEM_SERVICE = "modem";/*** Use with {@link #getSystemService} to retrieve a {@link
diff --git a/frameworks/base/core/java/android/os/IModemService.aidl b/frameworks/base/core/java/android/os/IModemService.aidl
new file mode 100755
index 0000000..13e0e6d
--- /dev/null
+++ b/frameworks/base/core/java/android/os/IModemService.aidl
@@ -0,0 +1,13 @@
+package android.os;
+
+/** {@hide} */
+interface IModemService
+{
+ int powerOn();
+ int powerOff();
+ int reset();
+ int wakeup();
+ int sleep();
+ boolean isWakeup();
+ boolean isPowerOn();
+}
diff --git a/frameworks/base/core/java/android/os/SystemModem.java b/frameworks/base/core/java/android/os/SystemModem.java
new file mode 100755
index 0000000..bbf16ca
--- /dev/null
+++ b/frameworks/base/core/java/android/os/SystemModem.java
@@ -0,0 +1,85 @@
+
+package android.os;
+
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.util.Log;
+
+/**
+ Mcu implementation that controls the main system mcu.
+
+ @hide
+*/
+public class SystemModem
+{
+ private static final String TAG = "modem";
+
+ private final IModemService mService;
+ public SystemModem()
+ {
+ mService = IModemService.Stub.asInterface(
+ ServiceManager.getService("modem"));
+ }
+
+ public SystemModem(Context context)
+ {
+ mService = IModemService.Stub.asInterface(
+ ServiceManager.getService("modem"));
+ }
+
+ public int powerOn()
+ {
+ try {
+ return mService.powerOn();
+ } catch(Exception e) {}
+ return -1;
+ }
+
+ public int powerOff()
+ {
+ try {
+ return mService.powerOff();
+ } catch(Exception e) {}
+ return -1;
+ }
+
+ public int reset()
+ {
+ try {
+ return mService.reset();
+ } catch(Exception e) {}
+ return -1;
+ }
+
+ public int wakeup()
+ {
+ try {
+ return mService.wakeup();
+ } catch(Exception e) {}
+ return -1;
+ }
+
+ public int sleep()
+ {
+ try {
+ return mService.sleep();
+ } catch(Exception e) {}
+ return -1;
+ }
+
+ public boolean isWakeup()
+ {
+ try {
+ return mService.isWakeup();
+ } catch(Exception e) {}
+ return false;
+ }
+
+ public boolean isPowerOn()
+ {
+ try {
+ return mService.isPowerOn();
+ } catch(Exception e) {}
+ return false;
+ }
+}
diff --git a/frameworks/base/services/core/java/com/android/server/ModemService.java b/frameworks/base/services/core/java/com/android/server/ModemService.java
new file mode 100755
index 0000000..fec8323
--- /dev/null
+++ b/frameworks/base/services/core/java/com/android/server/ModemService.java
@@ -0,0 +1,58 @@
+package com.android.server;
+import android.os.IModemService;
+
+public class ModemService extends IModemService.Stub
+{
+ private static final String TAG = "ModemService";
+
+ /* call native c function to access hardware */
+ public int powerOn() throws android.os.RemoteException
+ {
+ return native_modemPowerOn();
+ }
+
+ public int powerOff() throws android.os.RemoteException
+ {
+ return native_modemPowerOff();
+ }
+
+ public int reset() throws android.os.RemoteException
+ {
+ return native_modemReset();
+ }
+
+ public int wakeup() throws android.os.RemoteException
+ {
+ return native_modemWakeup();
+ }
+
+ public int sleep() throws android.os.RemoteException
+ {
+ return native_modemSleep();
+ }
+
+ public boolean isWakeup() throws android.os.RemoteException
+ {
+ return native_modemIsWakeup() > 0;
+ }
+
+ public boolean isPowerOn() throws android.os.RemoteException
+ {
+ return native_modemIsPowerOn() > 0;
+ }
+
+ public ModemService()
+ {
+ native_modemOpen();
+ }
+
+ public static native int native_modemOpen();
+ public static native void native_modemClose();
+ public static native int native_modemPowerOn();
+ public static native int native_modemPowerOff();
+ public static native int native_modemReset();
+ public static native int native_modemWakeup();
+ public static native int native_modemSleep();
+ public static native int native_modemIsWakeup();
+ public static native int native_modemIsPowerOn();
+}
diff --git a/frameworks/base/services/core/jni/Android.mk b/frameworks/base/services/core/jni/Android.mk
index 67dda50..9e0e465 100755
--- a/frameworks/base/services/core/jni/Android.mk
+++ b/frameworks/base/services/core/jni/Android.mk
@@ -40,6 +40,7 @@ LOCAL_SRC_FILES += \$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \$(LOCAL_REL_DIR)/com_android_server_GpioService.cpp \$(LOCAL_REL_DIR)/com_android_server_McuService.cpp \
+ $(LOCAL_REL_DIR)/com_android_server_ModemService.cpp \$(LOCAL_REL_DIR)/com_android_server_PersistentDataBlockService.cpp \$(LOCAL_REL_DIR)/com_android_server_GraphicsStatsService.cpp \$(LOCAL_REL_DIR)/onload.cpp
diff --git a/frameworks/base/services/core/jni/com_android_server_ModemService.cpp b/frameworks/base/services/core/jni/com_android_server_ModemService.cpp
new file mode 100755
index 0000000..7805d00
--- /dev/null
+++ b/frameworks/base/services/core/jni/com_android_server_ModemService.cpp
@@ -0,0 +1,108 @@
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+#include <utils/misc.h>
+#include <utils/Log.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <hardware/modem_hal.h>
+
+namespace android
+{
+
+static struct modem_device_t* modemDevice;
+
+jint modemOpen(JNIEnv *env, jobject cls)
+{
+ jint err;
+ hw_module_t* module;
+ hw_device_t* device;
+
+ ALOGI("native modemOpen ...");
+
+ // hw_get_module finds the library by "modem" (this is the id of hal)
+ err = hw_get_module("modem", (hw_module_t const**)&module);
+ if(err == 0) {
+ // Get device : module->methods->open
+ err = module->methods->open(module, NULL, &device);
+ if(err == 0) {
+ // Call modem_open
+ modemDevice = (modem_device_t *)device;
+ return modemDevice->modem_open(modemDevice);
+ } else {
+ return -1;
+ }
+ }
+
+ return -1;
+}
+
+void modemClose(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemClose ...");
+}
+
+jint modemPowerOn(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemPowerOn");
+ return modemDevice->modem_poweron(modemDevice);
+}
+
+jint modemPowerOff(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemPowerOff");
+ return modemDevice->modem_poweroff(modemDevice);
+}
+
+jint modemReset(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemReset");
+ return modemDevice->modem_reset(modemDevice);
+}
+
+jint modemWakeup(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemWakeup");
+ return modemDevice->modem_wakeup(modemDevice);
+}
+jint modemSleep(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemSleep");
+ return modemDevice->modem_sleep(modemDevice);
+}
+jint modemIsWakeup(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemIsWakeup");
+ return modemDevice->modem_is_wakeup(modemDevice);
+}
+jint modemIsPowerOn(JNIEnv *env, jobject cls)
+{
+ ALOGI("native modemIsPowerOn");
+ return modemDevice->modem_is_poweron(modemDevice);
+}
+
+// Register native methods
+static const JNINativeMethod methods[] = {
+ {"native_modemOpen", "()I", (void *)modemOpen},
+ {"native_modemClose", "()V", (void *)modemClose},
+ {"native_modemPowerOn", "()I", (void *)modemPowerOn},
+ {"native_modemPowerOff", "()I", (void *)modemPowerOff},
+ {"native_modemReset", "()I", (void *)modemReset},
+ {"native_modemWakeup", "()I", (void *)modemWakeup},
+ {"native_modemSleep", "()I", (void *)modemSleep},
+ {"native_modemIsWakeup", "()I", (void *)modemIsWakeup},
+ {"native_modemIsPowerOn", "()I", (void *)modemIsPowerOn},
+};
+
+int register_android_server_ModemService(JNIEnv *env)
+{
+ // The Java method corresponding to the local method ModemService
+ return jniRegisterNativeMethods(env, "com/android/server/ModemService",
+ methods, NELEM(methods));
+}
+
+}
diff --git a/frameworks/base/services/core/jni/onload.cpp b/frameworks/base/services/core/jni/onload.cpp
index 0f8e3d8..182e0f3 100755
--- a/frameworks/base/services/core/jni/onload.cpp
+++ b/frameworks/base/services/core/jni/onload.cpp
@@ -41,6 +41,7 @@ int register_android_server_vr_VrManagerService(JNIEnv* env);int register_android_server_VibratorService(JNIEnv* env);int register_android_server_GpioService(JNIEnv* env);int register_android_server_McuService(JNIEnv* env);
+int register_android_server_ModemService(JNIEnv* env);int register_android_server_location_ContextHubService(JNIEnv* env);int register_android_server_location_GnssLocationProvider(JNIEnv* env);int register_android_server_connectivity_Vpn(JNIEnv* env);
@@ -86,6 +87,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)register_android_server_VibratorService(env);register_android_server_GpioService(env);register_android_server_McuService(env);
+ register_android_server_ModemService(env);register_android_server_SystemServer(env);register_android_server_location_ContextHubService(env);register_android_server_location_GnssLocationProvider(env);
diff --git a/frameworks/base/services/java/com/android/server/SystemServer.java b/frameworks/base/services/java/com/android/server/SystemServer.java
index e693dcd..5854aa9 100755
--- a/frameworks/base/services/java/com/android/server/SystemServer.java
+++ b/frameworks/base/services/java/com/android/server/SystemServer.java
@@ -805,6 +805,11 @@ public final class SystemServer {McuService mcu = new McuService();ServiceManager.addService("mcu", mcu);traceEnd();
+
+ traceBeginAndSlog("StartModemService");
+ ModemService modem = new ModemService();
+ ServiceManager.addService("modem", modem);
+ traceEnd();if (!disableConsumerIr) {traceBeginAndSlog("StartConsumerIrService");
diff --git a/hardware/libhardware/include/hardware/modem_hal.h b/hardware/libhardware/include/hardware/modem_hal.h
new file mode 100755
index 0000000..7e01717
--- /dev/null
+++ b/hardware/libhardware/include/hardware/modem_hal.h
@@ -0,0 +1,25 @@
+#ifndef ANDROID_MODEM_INTERFACE_H
+#define ANDROID_MODEM_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+struct modem_device_t {
+ struct hw_device_t common;
+
+ int (*modem_open)(struct modem_device_t* dev);
+ int (*modem_poweron)(struct modem_device_t* dev);
+ int (*modem_poweroff)(struct modem_device_t* dev);
+ int (*modem_reset)(struct modem_device_t* dev);
+ int (*modem_wakeup)(struct modem_device_t* dev);
+ int (*modem_sleep)(struct modem_device_t* dev);
+ int (*modem_is_wakeup)(struct modem_device_t* dev);
+ int (*modem_is_poweron)(struct modem_device_t* dev);
+};
+
+__END_DECLS
+
+#endif // ANDROID_mcu_INTERFACE_H
diff --git a/hardware/libhardware/modules/Android.mk b/hardware/libhardware/modules/Android.mk
index bc0b36b..d998ef9 100755
--- a/hardware/libhardware/modules/Android.mk
+++ b/hardware/libhardware/modules/Android.mk
@@ -12,5 +12,6 @@ hardware_modules := \vehicle \vr \gpio \
- mcu
+ mcu \
+ modeminclude $(call all-named-subdir-makefiles,$(hardware_modules))
diff --git a/hardware/libhardware/modules/modem/Android.mk b/hardware/libhardware/modules/modem/Android.mk
new file mode 100755
index 0000000..d6a90a6
--- /dev/null
+++ b/hardware/libhardware/modules/modem/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := modem.default
+
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_SRC_FILES := modem_hal.c
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/hardware/libhardware/modules/modem/modem_hal.c b/hardware/libhardware/modules/modem/modem_hal.c
new file mode 100755
index 0000000..a53c635
--- /dev/null
+++ b/hardware/libhardware/modules/modem/modem_hal.c
@@ -0,0 +1,211 @@
+#include <hardware/hardware.h>
+#include <cutils/log.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <hardware/modem_hal.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <utils/Log.h>
+
+#define DEVICE "/dev/tb_4g"
+
+// ioctl cmd
+#define TB_4G_IOC_MAGIC 'g'
+
+#define TB_4G_IOC_ENABLE _IOW(TB_4G_IOC_MAGIC, 1, int)
+#define TB_4G_IOC_POWER _IOW(TB_4G_IOC_MAGIC, 2, int)
+#define TB_4G_IOC_RESET _IOW(TB_4G_IOC_MAGIC, 3, int)
+#define TB_4G_IOC_WAKEUP _IOW(TB_4G_IOC_MAGIC, 4, int)
+#define TB_4G_IOC_GET_WAKEUP_STATUS _IOR(TB_4G_IOC_MAGIC, 5, int)
+
+#define TB_4G_IOC_MAXNR 5
+
+static int fd;
+
+static int modem_close(struct hw_device_t* device)
+{
+ close(fd);
+ return 0;
+}
+
+static int modem_open(struct modem_device_t* dev)
+{
+ fd = open(DEVICE, O_RDWR);
+ ALOGI("modem_open : %d", fd);
+
+ if(fd >= 0) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static int modem_poweron(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_poweron: data=%d, ret=%d", data, ret);
+
+ return ret;
+}
+
+static int modem_poweroff(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_poweroff: data=%d, ret=%d", data, ret);
+
+ return ret;
+}
+
+static int modem_reset(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ ret = ioctl(fd, TB_4G_IOC_RESET, &data);
+
+ ALOGI("modem_reset: data=%d, ret=%d", data, ret);
+
+ return ret;
+}
+
+static int modem_wakeup(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_wakeup: data=%d, ret=%d", data, ret);
+
+ return ret;
+}
+
+static int modem_sleep(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_sleep: data=%d, ret=%d", data, ret);
+
+ return ret;
+}
+
+static int modem_is_wakeup(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_is_wakeup: data=%d, ret=%d", data, ret);
+
+ return data;
+}
+
+static int modem_is_poweron(struct modem_device_t* dev)
+{
+ int ret = 0;
+ int data = 0;
+
+ if(fd < 0) {
+ ret = modem_open(dev);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+
+ //ret = ioctl(fd, TB_4G_IOC_POWER, &data);
+
+ ALOGI("modem_is_poweron: data=%d, ret=%d", data, ret);
+
+ return data;
+}
+
+
+static struct modem_device_t modem_dev = {
+ .common = {
+ .tag = HARDWARE_DEVICE_TAG,
+ .close = modem_close,
+ },
+ .modem_open = modem_open,
+ .modem_poweron = modem_poweron,
+ .modem_poweroff = modem_poweroff,
+ .modem_reset = modem_reset,
+ .modem_wakeup = modem_wakeup,
+ .modem_sleep = modem_sleep,
+ .modem_is_wakeup = modem_is_wakeup,
+ .modem_is_poweron = modem_is_poweron,
+};
+
+static int modem_device_open(const struct hw_module_t* module, const char* id,
+ struct hw_device_t** device)
+{
+ *device = &modem_dev;
+ return 0;
+}
+
+static struct hw_module_methods_t modem_module_methods = {
+ .open = modem_device_open,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .id = "modem",
+ .methods = &modem_module_methods,
+};
diff --git a/kernel/arch/arm/boot/dts/topband-ls.dtsi b/kernel/arch/arm/boot/dts/topband-ls.dtsi
index e96d8a7..0afbd90 100755
--- a/kernel/arch/arm/boot/dts/topband-ls.dtsi
+++ b/kernel/arch/arm/boot/dts/topband-ls.dtsi
@@ -116,6 +116,17 @@};};};
+
+ topband_4g: topband-4g {
+ status = "okay";
+ compatible = "topband,4g";
+
+ pwr-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ rst-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
+ wakeupin-gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+ wakeupout-gpios = <&gpio5 13 GPIO_ACTIVE_HIGH>;
+ en-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>; // GPIO0_B6
+ };};
diff --git a/kernel/arch/arm/configs/topband_pos_defconfig b/kernel/arch/arm/configs/topband_pos_defconfig
index 9753630..d8055c7 100755
--- a/kernel/arch/arm/configs/topband_pos_defconfig
+++ b/kernel/arch/arm/configs/topband_pos_defconfig
@@ -721,4 +721,5 @@ CONFIG_CRYPTO_SHA512_ARM=yCONFIG_CRYPTO_AES_ARM_BS=yCONFIG_N76E003_DRIVER=y
\ No newline at end of file
CONFIG_TOPBAND_GPIO_DRIVER=y
+CONFIG_TOPBAND_4G_DRIVER=y
\ No newline at end of file
diff --git a/kernel/drivers/misc/Kconfig b/kernel/drivers/misc/Kconfig
index f22ca49..0bfc6fc 100755
--- a/kernel/drivers/misc/Kconfig
+++ b/kernel/drivers/misc/Kconfig
@@ -578,4 +578,5 @@ source "drivers/misc/echo/Kconfig"source "drivers/misc/cxl/Kconfig"source "drivers/misc/n76e003/Kconfig"source "drivers/misc/topband_gpio/Kconfig"
+source "drivers/misc/tb-4g/Kconfig"endmenu
diff --git a/kernel/drivers/misc/Makefile b/kernel/drivers/misc/Makefile
index 2e97a69..76a90b3 100755
--- a/kernel/drivers/misc/Makefile
+++ b/kernel/drivers/misc/Makefile
@@ -63,3 +63,4 @@ obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.oobj-$(CONFIG_USB_CAM_GPIO) += usb_cam_gpio.oobj-$(CONFIG_N76E003_DRIVER) += n76e003/obj-$(CONFIG_TOPBAND_GPIO_DRIVER) += topband_gpio/
+obj-$(CONFIG_TOPBAND_4G_DRIVER) += tb-4g/
diff --git a/kernel/drivers/misc/tb-4g/Kconfig b/kernel/drivers/misc/tb-4g/Kconfig
new file mode 100755
index 0000000..bf721bd
--- /dev/null
+++ b/kernel/drivers/misc/tb-4g/Kconfig
@@ -0,0 +1,8 @@
+#
+# TOPBAND 4G driver configuration
+#
+config TOPBAND_4G_DRIVER
+ tristate "Topband 4G driver"
+ default n
+ help
+ Topband 4G driver for 4G modem power control
\ No newline at end of file
diff --git a/kernel/drivers/misc/tb-4g/Makefile b/kernel/drivers/misc/tb-4g/Makefile
new file mode 100755
index 0000000..562771e
--- /dev/null
+++ b/kernel/drivers/misc/tb-4g/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TOPBAND_4G_DRIVER) += tb_4g.o
\ No newline at end of file
diff --git a/kernel/drivers/misc/tb-4g/tb_4g.c b/kernel/drivers/misc/tb-4g/tb_4g.c
new file mode 100755
index 0000000..a7daa25
--- /dev/null
+++ b/kernel/drivers/misc/tb-4g/tb_4g.c
@@ -0,0 +1,467 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/idr.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/signal.h>
+#include <linux/pm.h>
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#include <linux/input.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+
+#define TB_4G_NAME "topband,4g"
+
+// ioctl cmd
+#define TB_4G_IOC_MAGIC 'g'
+
+#define TB_4G_IOC_ENABLE _IOW(TB_4G_IOC_MAGIC, 1, int)
+#define TB_4G_IOC_POWER _IOW(TB_4G_IOC_MAGIC, 2, int)
+#define TB_4G_IOC_RESET _IOW(TB_4G_IOC_MAGIC, 3, int)
+#define TB_4G_IOC_WAKEUP _IOW(TB_4G_IOC_MAGIC, 4, int)
+#define TB_4G_IOC_GET_WAKEUP_STATUS _IOR(TB_4G_IOC_MAGIC, 5, int)
+
+#define TB_4G_IOC_MAXNR 5
+
+struct tb_4g_data {
+ struct platform_device *platform_dev;
+ struct miscdevice tb_4g_device;
+
+ int pwr_gpio;
+ int rst_gpio;
+ int wakeupin_gpio;
+ int wakeupout_gpio;
+ int en_gpio;
+};
+
+static int tb_4g_gpio_set_value(int gpio, int value) {
+ if(gpio_is_valid(gpio)) {
+ gpio_set_value(gpio, value);
+ return 0;
+ }
+ return -1;
+}
+
+static int tb_4g_gpio_get_value(int gpio) {
+ if(gpio_is_valid(gpio)) {
+ return gpio_get_value(gpio);
+ }
+ return -1;
+}
+
+/**
+* @decs: 4G power on/off control, low level is effective,
+* pull down 2-3 seconds
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_power_ctl(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->pwr_gpio, 1);
+
+ usleep_range(2000*1000, 3000*1000); //2s ~ 3s
+ tb_4g_gpio_set_value(tb_4g->pwr_gpio, 0);
+}
+
+/**
+* @decs: 4G reset control, low level is effective,
+* pull down 130ms ~ 1s
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_reset(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->rst_gpio, 1);
+
+ usleep_range(130*1000, 1000*1000); //130ms ~ 1000ms
+ tb_4g_gpio_set_value(tb_4g->rst_gpio, 0);
+}
+
+/**
+* @decs: 4G wakeup control
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_wakeup(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->wakeupin_gpio, 1);
+}
+
+/**
+* @decs: 4G sleep control
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_sleep(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->wakeupin_gpio, 0);
+}
+
+/**
+* @decs: Open 4G power
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_enable(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->en_gpio, 1);
+}
+
+/**
+* @decs: Close 4G power
+* @param:
+* @return:
+* @other:
+*/
+static void tb_4g_disable(struct tb_4g_data *tb_4g) {
+ tb_4g_gpio_set_value(tb_4g->en_gpio, 0);
+}
+
+/**
+* @decs: Get 4G wakeup status
+* @param:
+* @return:
+* @other:
+*/
+static int tb_4g_get_wakeup_status(struct tb_4g_data *tb_4g) {
+ return tb_4g_gpio_get_value(tb_4g->wakeupout_gpio);
+}
+
+static void tb_4g_init(struct tb_4g_data *tb_4g) {
+ tb_4g_enable(tb_4g);
+ tb_4g_reset(tb_4g);
+ tb_4g_wakeup(tb_4g);
+ tb_4g_power_ctl(tb_4g);
+}
+
+static void tb_4g_free_io_port(struct tb_4g_data *tb_4g)
+{
+ if (gpio_is_valid(tb_4g->pwr_gpio)) {
+ gpio_free(tb_4g->pwr_gpio);
+ }
+
+ if (gpio_is_valid(tb_4g->rst_gpio)) {
+ gpio_free(tb_4g->rst_gpio);
+ }
+
+ if (gpio_is_valid(tb_4g->wakeupin_gpio)) {
+ gpio_free(tb_4g->wakeupin_gpio);
+ }
+
+ if (gpio_is_valid(tb_4g->wakeupout_gpio)) {
+ gpio_free(tb_4g->wakeupout_gpio);
+ }
+
+ if (gpio_is_valid(tb_4g->en_gpio)) {
+ gpio_free(tb_4g->en_gpio);
+ }
+ return;
+}
+
+static int tb_4g_parse_dt(struct device *dev,
+ struct tb_4g_data *tb_4g)
+{
+ struct device_node *np = dev->of_node;
+
+ tb_4g->pwr_gpio = of_get_named_gpio(np, "pwr-gpios", 0);
+ if (!gpio_is_valid(tb_4g->pwr_gpio)) {
+ dev_err(dev, "power gpio is invalid");
+ return -EINVAL;
+ }
+
+ tb_4g->rst_gpio = of_get_named_gpio(np, "rst-gpios", 0);
+ if (!gpio_is_valid(tb_4g->rst_gpio)) {
+ dev_err(dev, "reset gpio is invalid");
+ return -EINVAL;
+ }
+
+ tb_4g->wakeupin_gpio = of_get_named_gpio(np, "wakeupin-gpios", 0);
+ if (!gpio_is_valid(tb_4g->wakeupin_gpio)) {
+ dev_err(dev, "wakeupin gpio is invalid");
+ return -EINVAL;
+ }
+
+ tb_4g->wakeupout_gpio = of_get_named_gpio(np, "wakeupout-gpios", 0);
+ if (!gpio_is_valid(tb_4g->wakeupout_gpio)) {
+ dev_err(dev, "wakeupout gpio is invalid");
+ return -EINVAL;
+ }
+
+ tb_4g->en_gpio = of_get_named_gpio(np, "en-gpios", 0);
+ if (!gpio_is_valid(tb_4g->en_gpio)) {
+ dev_err(dev, "enable gpio is invalid");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tb_4g_request_io_port(struct tb_4g_data *tb_4g)
+{
+ int ret = 0;
+
+ if (gpio_is_valid(tb_4g->pwr_gpio)) {
+ ret = gpio_request(tb_4g->pwr_gpio, "tb_4g");
+ if (ret < 0) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "Failed to request pwr_gpio:%d, ERRNO:%d\n",
+ (s32)tb_4g->pwr_gpio, ret);
+ return -ENODEV;
+ }
+ gpio_direction_output(tb_4g->pwr_gpio, 0);
+ }
+
+ if (gpio_is_valid(tb_4g->rst_gpio)) {
+ ret = gpio_request(tb_4g->rst_gpio, "tb_4g");
+ if (ret < 0) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "Failed to request rst_gpio:%d, ERRNO:%d\n",
+ (s32)tb_4g->rst_gpio, ret);
+ return -ENODEV;
+ }
+ gpio_direction_output(tb_4g->rst_gpio, 0);
+ }
+
+ if (gpio_is_valid(tb_4g->wakeupin_gpio)) {
+ ret = gpio_request(tb_4g->wakeupin_gpio, "tb_4g");
+ if (ret < 0) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "Failed to request wakeupin_gpio:%d, ERRNO:%d\n",
+ (s32)tb_4g->wakeupin_gpio, ret);
+ return -ENODEV;
+ }
+ gpio_direction_output(tb_4g->wakeupin_gpio, 1);
+ }
+
+ if (gpio_is_valid(tb_4g->wakeupout_gpio)) {
+ ret = gpio_request(tb_4g->wakeupout_gpio, "tb_4g");
+ if (ret < 0) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "Failed to request wakeupout_gpio:%d, ERRNO:%d\n",
+ (s32)tb_4g->wakeupout_gpio, ret);
+ return -ENODEV;
+ }
+ gpio_direction_input(tb_4g->wakeupout_gpio);
+ }
+
+ if (gpio_is_valid(tb_4g->en_gpio)) {
+ ret = gpio_request(tb_4g->en_gpio, "tb_4g");
+ if (ret < 0) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "Failed to request en_gpio:%d, ERRNO:%d\n",
+ (s32)tb_4g->en_gpio, ret);
+ return -ENODEV;
+ }
+ gpio_direction_output(tb_4g->en_gpio, 1);
+ }
+
+ return ret;
+}
+
+static int tb_4g_dev_open(struct inode *inode, struct file *filp)
+{
+ int ret = 0;
+
+ struct tb_4g_data *tb_4g = container_of(filp->private_data,
+ struct tb_4g_data,
+ tb_4g_device);
+ filp->private_data = tb_4g;
+ dev_info(&tb_4g->platform_dev->dev,
+ "device node major=%d, minor=%d\n", imajor(inode), iminor(inode));
+
+ return ret;
+}
+
+static long tb_4g_dev_ioctl(struct file *pfile,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ int data = 0;
+ struct tb_4g_data *tb_4g = pfile->private_data;
+
+ if (_IOC_TYPE(cmd) != TB_4G_IOC_MAGIC) {
+ return -EINVAL;
+ }
+ if (_IOC_NR(cmd) > TB_4G_IOC_MAXNR) {
+ return -EINVAL;
+ }
+
+ if (_IOC_DIR(cmd) & _IOC_READ) {
+ ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ } else if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+ }
+ if (ret) {
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&data, (int *)arg, sizeof(int))) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "%s, copy from user failed\n", __func__);
+ return -EFAULT;
+ }
+
+ dev_info(&tb_4g->platform_dev->dev,
+ "%s, (%x, %lx): data=%d\n", __func__, cmd,
+ arg, data);
+
+ switch (cmd) {
+ case TB_4G_IOC_POWER:
+ tb_4g_power_ctl(tb_4g);
+ break;
+
+ case TB_4G_IOC_RESET:
+ tb_4g_reset(tb_4g);
+ break;
+
+ case TB_4G_IOC_WAKEUP:
+ if (data > 0) {
+ tb_4g_wakeup(tb_4g);
+ } else {
+ tb_4g_sleep(tb_4g);
+ }
+ break;
+
+ case TB_4G_IOC_GET_WAKEUP_STATUS:
+ ret = tb_4g_get_wakeup_status(tb_4g);
+ if (ret >= 0) {
+ if (copy_to_user((int *)arg, &ret, sizeof(int))) {
+ dev_err(&tb_4g->platform_dev->dev,
+ "%s, copy to user failed\n", __func__);
+ return -EFAULT;
+ }
+ } else {
+ dev_err(&tb_4g->platform_dev->dev,
+ "%s, get wakeup status failed\n", __func__);
+ return -EFAULT;
+ }
+ break;
+
+ case TB_4G_IOC_ENABLE:
+ if (data > 0) {
+ tb_4g_enable(tb_4g);
+ } else {
+ tb_4g_disable(tb_4g);
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct file_operations tb_4g_dev_fops = {
+ .owner = THIS_MODULE,
+ .open = tb_4g_dev_open,
+ .unlocked_ioctl = tb_4g_dev_ioctl
+};
+
+static int tb_4g_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct tb_4g_data *tb_4g;
+
+ tb_4g = devm_kzalloc(&pdev->dev, sizeof(*tb_4g), GFP_KERNEL);
+ if (tb_4g == NULL) {
+ dev_err(&pdev->dev, "Failed alloc ts memory");
+ return -ENOMEM;
+ }
+
+ if (pdev->dev.of_node) {
+ ret = tb_4g_parse_dt(&pdev->dev, tb_4g);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed parse dts\n");
+ goto exit_free_data;
+ }
+ }
+
+ tb_4g->platform_dev = pdev;
+
+ ret = tb_4g_request_io_port(tb_4g);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed request IO port\n");
+ goto exit_free_data;
+ }
+
+ platform_set_drvdata(pdev, tb_4g);
+
+ tb_4g_init(tb_4g);
+
+ tb_4g->tb_4g_device.minor = MISC_DYNAMIC_MINOR;
+ tb_4g->tb_4g_device.name = "tb_4g";
+ tb_4g->tb_4g_device.fops = &tb_4g_dev_fops;
+
+ ret = misc_register(&tb_4g->tb_4g_device);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed misc_register\n");
+ goto exit_free_io_port;
+ }
+
+ dev_info(&pdev->dev, "%s, over\n", __func__);
+ return 0;
+
+exit_free_io_port:
+ tb_4g_free_io_port(tb_4g);
+
+exit_free_data:
+ devm_kfree(&pdev->dev, tb_4g);
+
+ return ret;
+}
+
+static int tb_4g_remove(struct platform_device *pdev)
+{
+ struct tb_4g_data *tb_4g = platform_get_drvdata(pdev);
+ tb_4g_free_io_port(tb_4g);
+ kfree(tb_4g);
+
+ return 0;
+}
+
+static const struct of_device_id tb_4g_of_match[] = {
+ { .compatible = "topband,4g"},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, tb_4g_of_match);
+
+static struct platform_driver tb_4g_driver = {
+ .probe = tb_4g_probe,
+ .remove = tb_4g_remove,
+ .driver = {
+ .name = TB_4G_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = tb_4g_of_match,
+ },
+};
+
+module_platform_driver(tb_4g_driver);
+
+MODULE_AUTHOR("shenhb@topband.com.cn");
+MODULE_DESCRIPTION("Topband 4G driver for 4G modem power control");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/kernel/zboot.img b/kernel/zboot.img
new file mode 100644
index 0000000..b080ab6
Binary files /dev/null and b/kernel/zboot.img differ
diff --git a/system/core/rootdir/ueventd.rc b/system/core/rootdir/ueventd.rc
index c473e89..c386231 100755
--- a/system/core/rootdir/ueventd.rc
+++ b/system/core/rootdir/ueventd.rc
@@ -68,6 +68,7 @@ subsystem sound# for topband/dev/topband_gpio 0666 system system/dev/n76e003 0666 system system
+/dev/tb_4g 0666 system system# these should not be world writable/dev/diag 0660 radio radio
使用
1.在 APP 源码 aidl/android/os/ 目录下新建 IModemService.aidl,如下:
package android.os;/** {@hide} */
interface IModemService
{int powerOn();int powerOff();int reset();int wakeup();int sleep();boolean isWakeup();boolean isPowerOn();
}
2.参考下面源码调用 4G 模块相关 API
package com.ayst.sample.items.modem;import android.annotation.SuppressLint;
import android.content.Context;
import android.os.IBinder;
import android.os.IModemService;
import android.os.RemoteException;
import android.util.Log;import java.lang.reflect.Method;/*** Created by Administrator on 2018/11/6.*/public class Modem {private IModemService mModemService;@SuppressLint("WrongConstant")public Modem(Context context) {Method method = null;try {method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);IBinder binder = (IBinder) method.invoke(null, new Object[]{"modem"});mModemService = IModemService.Stub.asInterface(binder);if (mModemService == null) {Log.i("Modem", "mModemService is null");}} catch (Exception e) {e.printStackTrace();}}public int powerOn() {if (null != mModemService) {try {return mModemService.powerOn();} catch (RemoteException e) {e.printStackTrace();}}return -1;}public int powerOff() {if (null != mModemService) {try {return mModemService.powerOff();} catch (RemoteException e) {e.printStackTrace();}}return -1;}public int reset() {if (null != mModemService) {try {Log.i("Modem", "reset");return mModemService.reset();} catch (RemoteException e) {e.printStackTrace();}}return -1;}public int wakeup() {if (null != mModemService) {try {return mModemService.wakeup();} catch (RemoteException e) {e.printStackTrace();}}return -1;}public int sleep() {if (null != mModemService) {try {return mModemService.sleep();} catch (RemoteException e) {e.printStackTrace();}}return -1;}public boolean isWakeup() {if (null != mModemService) {try {return mModemService.isWakeup();} catch (RemoteException e) {e.printStackTrace();}}return false;}public boolean isPowerOn() {if (null != mModemService) {try {return mModemService.isPowerOn();} catch (RemoteException e) {e.printStackTrace();}}return false;}}