1. 如何在底层添加一个设备节点,并封装到JNI 供APP调用(framework servermanager&NDK) 以驱Camera旋转马达为例,Camera旋转马达的GPIO的拉高拉低与camera的上电下电一致,所以添加到camera的驱动下
暴露出接口给其他设备调用
EXPORT_SYMBOL(kdCISModulePowerOn);,驱动给出)
under path:
alps/kernel-3.10/drivers/misc/mediatek/mach/mt6735/land6735_65u_l1/camera/camera/kd_camera_hw.c
2. 接下我们要创建一个设备节点来访问这个旋转马达
2.1 仿照vibrator(振动马达)的驱动,新建一个camera_vibrator
under path:
$: alps/kernel-3.10/drivers/misc/mediatek
$: makedir camera_vibrator
2.2 添加一个camera_vibrator 的驱动文件 和一个make文件:
camera_vibrator.c 和 Makefile (copy vibrator下的文件并进行修改)
camera_vibrator.c
/******************************************************************************
* mt6575_vibrator.c - MT6575 Android Linux Vibrator Device Driver
*
* Copyright 2009-2010 MediaTek Co.,Ltd.
*
* DESCRIPTION:
* This file provid the other drivers vibrator relative functions
*
******************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define VERSION "v 0.1"
#define VIB_DEVICE "camera_vibrator"
/******************************************************************************
Error Code No.
******************************************************************************/
#define RSUCCESS 0
//打开设备节点
static int cameravibrator_open(struct inode *inode, struct file *filp)
{
printk("luobogpio_open
");
return 0;
}
//读取设备节点
static ssize_t cameravibrator_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos)
{
if (ptr == NULL)
printk("%s: user space address is NULL
", __func__);
return sizeof(int);
}
// I/O口控制,执行具体操作
static long cameravibrator_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long ret = 0;
printk("luobogpio_ioctl: cmd = %d arg = %ld
",cmd, arg);
switch (cmd){
case 0:
printk("gpio_request
");
break;
case 1:
printk("gpio_direction_output
");
break;
case 3:
printk("gpio_free
");
break;
default:
printk("unknown ioctl cmd!
");
ret = -EINVAL;
break;
}
return ret;
}
#ifdef CONFIG_COMPAT
static long cameravibrator_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
return cameravibrator_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#else
#define spidev_compat_ioctl NULL
#endif /* CONFIG_COMPAT */
//关闭,释放资源
static int cameravibrator_release(struct inode *inode, struct file *filp)
{
printk("luobogpio_release
");
return 0;
}
//注册设备点的操作(类似java里的上下文传递)
static const struct file_operations cameravibrator_fops = {
.owner = THIS_MODULE,
.open = cameravibrator_open,
.read = cameravibrator_read,
.unlocked_ioctl = cameravibrator_ioctl,
.compat_ioctl = cameravibrator_compat_ioctl,
.release = cameravibrator_release,
};
//注册设备节点
static struct miscdevice cameravibrator_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "cameravibrator",
.fops = &cameravibrator_fops,
};
static int vib_probe(struct platform_device *pdev)
{
int ret=-1;
ret = misc_register(&cameravibrator_dev);
if (ret < 0){
printk("ac_usb_switch register err!
");
return ret; }
printk("func: %s
", __func__);
return 0;
}
static int vib_remove(struct platform_device *pdev)
{
printk("[ vib_remove] vib_mod_init
");
return 0;
}
static void vib_shutdown(struct platform_device *pdev)
{
printk("[vib_shutdown] vib_mod_init
");
}
/******************************************************************************
Device driver structure
*****************************************************************************/
//注册设备
static struct platform_driver vibrator_driver = {
.probe = vib_probe,
.remove = vib_remove,
.shutdown = vib_shutdown,
.driver = { .name = VIB_DEVICE, .owner = THIS_MODULE, },
};
//注册驱动
static struct platform_device vibrator_device = {
.name = VIB_DEVICE,
.id = -1,
};
//初始化
static int cameravibrator_mod_init(void)
{
s32 ret;
printk("[camera vibrator] vib_mod_init
");
ret = platform_device_register(&vibrator_device);
if (ret != 0) {
printk("[vibrator]Unable to register vibrator device (%d)
", ret);
eturn ret; }
ret = platform_driver_register(&vibrator_driver);
if (ret) {
printk("[vibrator]Unable to register vibrator driver (%d)
", ret);
return ret; }
return RSUCCESS;
}
/******************************************************************************
* vib_mod_exit
* DESCRIPTION: PARAMETERS: RETURNS: NOTES:
* Free the device driver ! None None None
******************************************************************************/
static void cameravibrator_mod_exit(void)
{
printk("[vibrator]vib_mod_exit Done
");
}
module_init(cameravibrator_mod_init);
module_exit(cameravibrator_mod_exit);
MODULE_AUTHOR("MediaTek Inc.");
MODULE_DESCRIPTION("MTK Vibrator Driver (VIB)");
MODULE_LICENSE("GPL");
Makefile 文件如下
include $(srctree)/drivers/misc/mediatek/Makefile.custom
obj-y += camera_vibrator.o
#obj-$(CONFIG_MTK_VIBRATOR) := camera_vibrator.o
#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/(屏蔽)
3. 在当前目录下这个对Makefile.mt6735 、Makefile.custom、Makefile修改 添加 camera_vibrort
Makefile.mt6735 :
Makefile:
4.编译
编译内核
$: make -j8 kernel 2>&1 | tee kernel.log(生成log,出错可以查看),为了检测是否生成对应的camera_vibrator.o
文件,你可以定位到out目录,执行 find -name camera_vibrator.o,或者到对应的目录下查看
under path:alps/out/target/product/land6735_65u_l1/obj/KERNEL_OBJ/drivers/misc/mediatek
打包bootimage
$: make bootimage
5.烧录bootimage
6. Boot Device 查看设备节点是否创建
cameravibrator设备节点已经创建,权限属于Root权限,在下一篇介绍如何得到全部权限
1. 如何在底层添加一个设备节点,并封装到JNI 供APP调用(framework servermanager&NDK) 以驱Camera旋转马达为例,Camera旋转马达的GPIO的拉高拉低与camera的上电下电一致,所以添加到camera的驱动下
暴露出接口给其他设备调用
EXPORT_SYMBOL(kdCISModulePowerOn);,驱动给出)
under path:
alps/kernel-3.10/drivers/misc/mediatek/mach/mt6735/land6735_65u_l1/camera/camera/kd_camera_hw.c
2. 接下我们要创建一个设备节点来访问这个旋转马达
2.1 仿照vibrator(振动马达)的驱动,新建一个camera_vibrator
under path:
$: alps/kernel-3.10/drivers/misc/mediatek
$: makedir camera_vibrator
2.2 添加一个camera_vibrator 的驱动文件 和一个make文件:
camera_vibrator.c 和 Makefile (copy vibrator下的文件并进行修改)
camera_vibrator.c
/******************************************************************************
* mt6575_vibrator.c - MT6575 Android Linux Vibrator Device Driver
*
* Copyright 2009-2010 MediaTek Co.,Ltd.
*
* DESCRIPTION:
* This file provid the other drivers vibrator relative functions
*
******************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define VERSION "v 0.1"
#define VIB_DEVICE "camera_vibrator"
/******************************************************************************
Error Code No.
******************************************************************************/
#define RSUCCESS 0
//打开设备节点
static int cameravibrator_open(struct inode *inode, struct file *filp)
{
printk("luobogpio_open
");
return 0;
}
//读取设备节点
static ssize_t cameravibrator_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos)
{
if (ptr == NULL)
printk("%s: user space address is NULL
", __func__);
return sizeof(int);
}
// I/O口控制,执行具体操作
static long cameravibrator_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long ret = 0;
printk("luobogpio_ioctl: cmd = %d arg = %ld
",cmd, arg);
switch (cmd){
case 0:
printk("gpio_request
");
break;
case 1:
printk("gpio_direction_output
");
break;
case 3:
printk("gpio_free
");
break;
default:
printk("unknown ioctl cmd!
");
ret = -EINVAL;
break;
}
return ret;
}
#ifdef CONFIG_COMPAT
static long cameravibrator_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
return cameravibrator_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#else
#define spidev_compat_ioctl NULL
#endif /* CONFIG_COMPAT */
//关闭,释放资源
static int cameravibrator_release(struct inode *inode, struct file *filp)
{
printk("luobogpio_release
");
return 0;
}
//注册设备点的操作(类似java里的上下文传递)
static const struct file_operations cameravibrator_fops = {
.owner = THIS_MODULE,
.open = cameravibrator_open,
.read = cameravibrator_read,
.unlocked_ioctl = cameravibrator_ioctl,
.compat_ioctl = cameravibrator_compat_ioctl,
.release = cameravibrator_release,
};
//注册设备节点
static struct miscdevice cameravibrator_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "cameravibrator",
.fops = &cameravibrator_fops,
};
static int vib_probe(struct platform_device *pdev)
{
int ret=-1;
ret = misc_register(&cameravibrator_dev);
if (ret < 0){
printk("ac_usb_switch register err!
");
return ret; }
printk("func: %s
", __func__);
return 0;
}
static int vib_remove(struct platform_device *pdev)
{
printk("[ vib_remove] vib_mod_init
");
return 0;
}
static void vib_shutdown(struct platform_device *pdev)
{
printk("[vib_shutdown] vib_mod_init
");
}
/******************************************************************************
Device driver structure
*****************************************************************************/
//注册设备
static struct platform_driver vibrator_driver = {
.probe = vib_probe,
.remove = vib_remove,
.shutdown = vib_shutdown,
.driver = { .name = VIB_DEVICE, .owner = THIS_MODULE, },
};
//注册驱动
static struct platform_device vibrator_device = {
.name = VIB_DEVICE,
.id = -1,
};
//初始化
static int cameravibrator_mod_init(void)
{
s32 ret;
printk("[camera vibrator] vib_mod_init
");
ret = platform_device_register(&vibrator_device);
if (ret != 0) {
printk("[vibrator]Unable to register vibrator device (%d)
", ret);
eturn ret; }
ret = platform_driver_register(&vibrator_driver);
if (ret) {
printk("[vibrator]Unable to register vibrator driver (%d)
", ret);
return ret; }
return RSUCCESS;
}
/******************************************************************************
* vib_mod_exit
* DESCRIPTION: PARAMETERS: RETURNS: NOTES:
* Free the device driver ! None None None
******************************************************************************/
static void cameravibrator_mod_exit(void)
{
printk("[vibrator]vib_mod_exit Done
");
}
module_init(cameravibrator_mod_init);
module_exit(cameravibrator_mod_exit);
MODULE_AUTHOR("MediaTek Inc.");
MODULE_DESCRIPTION("MTK Vibrator Driver (VIB)");
MODULE_LICENSE("GPL");
Makefile 文件如下
include $(srctree)/drivers/misc/mediatek/Makefile.custom
obj-y += camera_vibrator.o
#obj-$(CONFIG_MTK_VIBRATOR) := camera_vibrator.o
#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/(屏蔽)
3. 在当前目录下这个对Makefile.mt6735 、Makefile.custom、Makefile修改 添加 camera_vibrort
Makefile.mt6735 :
Makefile:
4.编译
编译内核
$: make -j8 kernel 2>&1 | tee kernel.log(生成log,出错可以查看),为了检测是否生成对应的camera_vibrator.o
文件,你可以定位到out目录,执行 find -name camera_vibrator.o,或者到对应的目录下查看
under path:alps/out/target/product/land6735_65u_l1/obj/KERNEL_OBJ/drivers/misc/mediatek
打包bootimage
$: make bootimage
5.烧录bootimage
6. Boot Device 查看设备节点是否创建
cameravibrator设备节点已经创建,权限属于Root权限,在下一篇介绍如何得到全部权限