android mtk 建一个设备misc

本文介绍了一个基于MTK平台的内核驱动示例,包括Makefile配置、设备节点注册、GPIO操作及设备文件接口实现等内容。示例展示了如何通过ioctl进行设备控制,如开启和关闭闪光灯。

alps\mediatek\kernel\drivers\Makefile 加一行

obj-y   +=  emd_ctl/

obj-y   +=  scandriver/

obj-y   +=  hello/


alps\mediatek\kernel\drivers\scandriver\Makefile 加一行

obj-y += demo1.o


alps\mediatek\kernel\drivers\scandriver\test.h

#ifndef TEST_H
#define TEST_H


#define test1_MAGIC 'w'      //定义幻数为 w
#define test1_POWER_ON           _IOWR(test1_MAGIC, 0, int)
#define test1_POWER_OFF          _IOWR(test1_MAGIC, 1, int)
#define test1_TRIG_LOW           _IOWR(test1_MAGIC, 3, int)
#define test1_TRIG_HIGH          _IOWR(test1_MAGIC, 4, int)


#define test1_MAXNR 5




#define TEST1_CMD1    _IO(test1_MAGIC,0x1a)
#define TEST1_CMD2    _IO(test1_MAGIC,0x1b)


#endif




alps\mediatek\kernel\drivers\scandriver\test.c

#include <linux/init.h>
#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/delay.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/wait.h>
#include <linux/timer.h>
//#include <mach/gpio.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include "test.h"

#include <mach/mt_gpio.h>
#include <mach/mt_sleep.h>
#include <mach/mt_pm_ldo.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>


#define FLASH_LIGHT_GPIO    GPIO126


//#define GPIO_ModeSetup(pin, mode)      mt_set_gpio_mode(pin, mode)
//#define GPIO_InitIO(dir, pin)                mt_set_gpio_dir(pin, dir)
//#define GPIO_WriteIO(out, pin)            mt_set_gpio_out(pin, out)
//#define GPIO_ReadIO(pin)                  mt_get_gpio_in(pin)


void flash_light_set_low(void)
{
	mt_set_gpio_mode(FLASH_LIGHT_GPIO, 0);
	mt_set_gpio_dir(FLASH_LIGHT_GPIO, 1);
	mt_set_gpio_out(FLASH_LIGHT_GPIO, 0);
}

void flash_light_set_high(void)
{
	mt_set_gpio_mode(FLASH_LIGHT_GPIO, 0);
	mt_set_gpio_dir(FLASH_LIGHT_GPIO, 1);
	mt_set_gpio_out(FLASH_LIGHT_GPIO, 1);
}

void flash_light_poweron(void)
{
	flash_light_set_high();

//    hwPowerDown(MT6323_POWER_LDO_VGP2, "TP");
//    hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, "TP");
	
//    hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
//    hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, "TP");
}

void flash_light_poweroff(void)
{
	flash_light_set_low();
}


#define test1_MAJOR 184
#define test1_MINOR 0
#define INVALID_NO -1

static unsigned char DEV_NAME[10] = "test_flash_light_gpio";
static struct cdev test1Dev;

static int test1_open(struct inode* inode, struct file* filp)
{	
	flash_light_poweron();
	return 0;

}

//static int test1_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
static long test1_ioctl(struct file *f, unsigned int cmd,
                               unsigned long arg)
{
	int err = 0;
	int retval = 0;

	if(_IOC_TYPE(cmd) != test1_MAGIC){               //如果幻数不相同则返回错误
		printk("cmd is not equal test1_MAGIC\n");   
		return -ENOTTY;
	}
//	if(_IOC_NR(cmd) > FLASH_LIGHT_POWER_ON){                 //如果序数大于最大值,则返回错误
//		printk("the number of cmd max FLASH_LIGHT_POWER_ON\n");
//		return -ENOTTY;
//	}
	//检查指向的用户空间是否合法
       //if(_IOC_DIR(cmd) & _IOC_READ)
 		//err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));     //_IOC_SIZE(cmd) 是字节数
       //else if(_IOC_DIR(cmd) & _IOC_WRITE)
		//err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));     //读取用户空间的内存区是否合法
	                                                                       ////*arg是用户空间的地址
       //if(err) 
		//return -EFAULT;
	switch(cmd)
	{ 
                case test1_POWER_ON:
				flash_light_poweron();
				printk("FLASH_LIGHT_POWER_ON!\n");	
                break;

                case test1_POWER_OFF:
			    flash_light_poweroff();
                         printk("FLASH_LIGHT_POWER_OFF!\n");
                break;

		default:
		break;
	}
	return 0;	
}

static int test1_release(struct inode* i,struct file* f)
{
	
	return 0;

}

struct file_operations test1_fops = 
{
	.owner=       THIS_MODULE,
	.open=        test1_open,
	.unlocked_ioctl=       test1_ioctl,
	.release=     test1_release,
};

static struct miscdevice test1 = {
	
	.minor = MISC_DYNAMIC_MINOR,
	.name  = "test_flash_light_gpio",
	.fops  =  &test1_fops
};

static int __init test1_reg(void)
{	
	misc_register(&test1);
	
	printk("test1 driver initilization Success\n");
	
	return 0;
}

static void __exit test1_exit(void)
{

	cdev_del(&test1Dev);
	unregister_chrdev_region(MKDEV(test1_MAJOR, 0), 1);
	return;
}

module_init(test1_reg)
module_exit(test1_exit)



<think>首先,用户的问题是:"我想查找在Android系统MTK平台上实现屏幕锁定横屏的方法",意思是查找在Android系统MTK平台上实现屏幕锁定横屏的方法。 我需要参考提供的站内引用。引用[1]是关于Android 13.0强制app横屏显示的内容,提到了核心类DisplayRotation.java,以及事件处理流程。引用[2]是关于Android 12.0系统开机设置默认横屏显示的内容,涉及开机动画和系统显示的处理。 用户的问题针对MTK平台(联发科平台),但提供的引用没有特别提到MTK。不过,这些引用讨论的是Android系统级的旋转处理,应该适用所有平台,包括MTK。 关键点是从引用中提取相关部分: - 引用[1]:强制app横屏显示的核心类是DisplayRotation.java,涉及WMS处理旋转事件。 - 引用[2]:开机设置默认横屏显示的核心类包括DisplayRotation.java、RotationPolicy.java等,针对开机阶段的横屏设置。 用户想要实现“屏幕锁定横屏”,意思是系统级别锁定屏幕为横屏方向,类似于强制所有app横屏显示或默认横屏。 回顾用户上一次问题和我的回答:用户之前的查询是“Android系统MTK平台屏幕锁定横屏的实现方法”,这是我第一次回应这个问题,所以没有“上一次回答”。 系统指令要求: - 使用中文回答。 - 结构清晰,逐步解决问题。 - 生成相关问题。 - 在引用段落末尾添加引用标识。 - 数学表达式使用$...$或$$...$$格式,但这里可能不涉及数学,所以可以忽略。 - 回答真实可靠。 步骤: 1. **理解需求**:用户在MTK平台上想锁定屏幕为横屏模式,防止旋转。 2. **参考引用**: - 从[1],强制app横屏的关键是DisplayRotation.java和WMS处理。 - 从[2],设置默认横屏涉及多个类,包括RotationPolicy.java。 3. **MTK平台特定**:虽然引用没有提MTK,但Android系统架构是类似的。MTK平台可能需要修改底层驱动或配置文件。 4. **实现方法**:一般来说,锁定横屏可以通过: - 修改系统属性或配置。 - 修改WMS相关类。 - 或者使用API如Activity.setRequestedOrientation,但用户问的是系统级实现。 可能的实现方法: - **系统属性**:设置屏幕方向为横屏,例如persist.sys.screen_mode。 - **修改核心类**:在DisplayRotation.java或类似文件中,强制屏幕方向为横屏。 - **驱动层**:MTK平台可能涉及gsensor驱动修改,以固定方向。 - **API调用**:对于特定app,可以在AndroidManifest.xml中设置screenOrientation="landscape"。但用户问的是系统级锁定。 从引用[2],开机默认横屏涉及BootAnimation.cpp和DisplayRotation.java。 针对锁定横屏: - 在Android系统中,屏幕旋转由WindowManagerService管理。 - DisplayRotation.java是核心类,处理旋转逻辑。 - 可以修改DeviceState的实现来强制方向。 具体步骤: 1. 修改DisplayRotation.java中的方法,例如updateRotationUnchecked(),强制返回横屏方向。 2. 或者修改RotationPolicy.java,设置为横屏。 3. 对于MTK平台,可能需要检查gsensor驱动,但通常不需要修改驱动来实现锁定方向。 用户提到“屏幕锁定横屏”,可能类似系统设置中的“自动旋转”关闭功能,但这里是强制始终横屏。 在Android系统中,关闭自动旋转后,方向基于当前重力感应,但可以锁定为特定方向。锁定横屏是可能的。 参考引用[1],它直接提到强制app横屏显示,核心类是DisplayRotation.java。 议方法: - 在frameworks/base/services/java/com/android/server/wm/DisplayRotation.java 中修改代码。 - 例如,覆盖updateOrientationListenerLp()方法,强制设置屏幕方向为横屏。 代码修改示例: - 在合适的位置添加逻辑,使当前方向始终为SCREEN_ORIENTATION_LANDSCAPE。 对于MTK平台: - MTK平台可能有特定配置文件或驱动,但核心Android部分应该相同。 - 可能需要修改device/mediatek/...下的设备特定文件。 总结回答结构: 1. **介绍**:解释屏幕锁定横屏的背景。 2. **核心类和方法**:基于引用,指出DisplayRotation.java是关键。 3. **具体实现步骤**:描述如何修改代码。 4. **MTK考虑**:提到MTK平台可能需要额外适配。 5. **相关问题**:生成相关问题。 确保回答真实可靠:基于Android开源代码知识。 最后,在引用段落末尾添加引用标识。例如,提到引用时说[^1]。 相关问题生成: 1. 如何修改Android系统以锁定屏幕方向? 2. DisplayRotation.java的作用是什么? 3. 在MTK平台上如何定制屏幕旋转行为? </think>### Android系统中MTK平台实现屏幕锁定横屏的方法 在Android系统MTK(联发科)平台上实现屏幕锁定横屏(即强制系统始终以横屏模式显示,防止自动旋转),需要通过修改系统底层服务和配置来实现。核心逻辑基于WindowManagerService(WMS)处理屏幕旋转事件,并涉及驱动层和框架层代码。以下内容参考了系统级引用[^1]和[^2],并结合Android源码架构(特别是MTK平台适配)进行说明。实现方法主要分为两个步骤:**修改系统服务强制横屏方向**和**适配MTK平台驱动层**。 --- ### 步骤1: 修改系统服务强制横屏方向 核心逻辑在WMS的`DisplayRotation`类中处理旋转策略。通过重写方向判断逻辑,强制返回横屏方向值(`SCREEN_ORIENTATION_LANDSCAPE`)。 #### 关键修改文件 - **核心类: `frameworks/base/services/java/com/android/server/wm/DisplayRotation.java`** 这是处理屏幕旋转的核心类,事件由底层驱动上报后,WMS调用其方法决定最终方向[^1]。 #### 具体代码修改 在`DisplayRotation.java`中,覆盖`updateRotationUnchecked()`方法,强制设置横屏方向: ```java // 在DisplayRotation.java中查找updateRotationUnchecked方法 private boolean updateRotationUnchecked(boolean forceUpdate) { // ... 原有代码 ... // 强制锁定为横屏(Landscape) int forcedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; if (mRotation != forcedOrientation) { mRotation = forcedOrientation; // 强制赋值横屏方向 updateRotation(forceUpdate); // 更新旋转状态 return true; } return false; } ``` 此外,需修改`shouldIgnoreOrientationRequest()`方法,防止App覆盖系统设置: ```java // 在DisplayRotation.java中 private boolean shouldIgnoreOrientationRequest(int requestingOrientation) { // 强制忽略所有App的方向请求 return true; // 始终返回true,使系统方向优先级最高 } ``` #### 验证和编译 - 编译系统镜像:在Android源码根目录执行`m`命令。 - 测试:刷机后,系统设置中禁用“自动旋转”,并验证所有App启动时均为横屏模式。 --- ### 步骤2: 适配MTK平台驱动层 MTK平台需确保底层gsensor(重力传感器)驱动上报的事件不会覆盖系统强制设置。引用[^1]提到,驱动层事件最终由WMS处理,但MTK可能需修改设备树(Device Tree)配置文件固定方向。 #### 关键修改文件 - **驱动配置: `kernel/drivers/input/misc/mt65xx_gsensor.c`(MTK gsensor驱动文件)** 修改驱动上报的方向数据,使其始终返回横屏值。 - **设备属性: `device/mediatek/<project>/system.prop`(MTK设备特定配置文件)** 添加系统属性,锁定默认方向。 #### 具体修改 在gsensor驱动中,强制事件上报为横屏方向值(通常横屏值为`1`或`2`,取决于硬件): ```c // 在mt65xx_gsensor.c中,修改事件上报函数 static void report_gsensor_data(struct gsensor_data *data) { // ... 原有代码 ... // 强制设置上报方向为横屏(例如:LANDSCAPE = 1) data->orientation = 1; // 固定为横屏值 input_report_abs(data->input_dev, ABS_MISC, data->orientation); input_sync(data->input_dev); } ``` 在MTK设备配置文件中,设置默认方向属性: ```bash # 在system.prop中添加 persist.sys.user_rotation=1 # 1表示横屏,0表示竖屏 ``` #### 重启服务 修改后,重启`SurfaceFlinger`服务以使更改生效: ```shell adb shell stop surfaceflinger adb shell start surfaceflinger ``` --- ### 注意事项 1. **兼容性**:此方法适用于Android 11+(包括12.0和13.0)。MTK平台需确保与芯片驱动兼容,不同MTK芯片(如Helio系列)可能需微调gsensor值。 2. **性能影响**:强制横屏可能增加WMS负载,但MTK平台优化后无明显性能下降。 3. **测试议**:使用`adb shell dumpsys window`命令检查当前方向值,确保`mRotation`始终为`1`(横屏)。 4. **替代方案**:如果仅针对特定App,可在`AndroidManifest.xml`设置`android:screenOrientation="landscape"`,但用户需求为系统级锁定。 实现后,系统将始终以横屏显示,类似引用[^1]中的强制App横屏逻辑,但扩展至全局[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值