1.
如何在底层添加一个设备节点,并封装到JNI 供APP调用(framework servermanager&NDK)
以驱Camera旋
转马达为例,Camera旋转马达的GPIO的拉高拉低与camera的上电下电一致,所以添加到camera的驱动下
暴露出接口给其他设备调用
EXPORT_SYMBOL(kdCISModulePowerOn);,驱动给出)
alps/kernel-3.10/drivers/misc/mediatek/mach/mt6735/land6735_65u_l1/camera/camera/kd_camera_hw.c
|
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下的文件并进行修改)
5.烧录bootimage
|
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 <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/device.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/jiffies.h> #include <linux/timer.h> #include <mach/mt_typedefs.h> #include <linux/miscdevice.h> #include <linux/err.h> #include <linux/slab.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <dt-bindings/gpio/gpio.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/fb.h> #include <linux/backlight.h> #include <linux/err.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/slab.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #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\n"); 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\n", __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\n",cmd, arg); switch (cmd){ case 0: printk("gpio_request\n"); break; case 1: printk("gpio_direction_output\n"); break; case 3: printk("gpio_free\n"); break; default: printk("unknown ioctl cmd!\n"); 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\n"); 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!\n"); return ret; } printk("func: %s\n", __func__); return 0; } static int vib_remove(struct platform_device *pdev) { printk("[ vib_remove] vib_mod_init\n"); return 0; } static void vib_shutdown(struct platform_device *pdev) { printk("[vib_shutdown] vib_mod_init\n"); } /****************************************************************************** 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\n"); ret = platform_device_register(&vibrator_device); if (ret != 0) { printk("[vibrator]Unable to register vibrator device (%d)\n", ret); eturn ret; } ret = platform_driver_register(&vibrator_driver); if (ret) { printk("[vibrator]Unable to register vibrator driver (%d)\n", 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\n"); } 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
cameravibrator设备节点已经创建,权限属于Root权限,在下一篇介绍如何得到全部权限
1.
如何在底层添加一个设备节点,并封装到JNI 供APP调用(framework servermanager&NDK)
以驱Camera旋
转马达为例,Camera旋转马达的GPIO的拉高拉低与camera的上电下电一致,所以添加到camera的驱动下
暴露出接口给其他设备调用
EXPORT_SYMBOL(kdCISModulePowerOn);,驱动给出)
alps/kernel-3.10/drivers/misc/mediatek/mach/mt6735/land6735_65u_l1/camera/camera/kd_camera_hw.c
|
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下的文件并进行修改)
5.烧录bootimage
|
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 <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/device.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/jiffies.h> #include <linux/timer.h> #include <mach/mt_typedefs.h> #include <linux/miscdevice.h> #include <linux/err.h> #include <linux/slab.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <dt-bindings/gpio/gpio.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/fb.h> #include <linux/backlight.h> #include <linux/err.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/slab.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #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\n"); 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\n", __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\n",cmd, arg); switch (cmd){ case 0: printk("gpio_request\n"); break; case 1: printk("gpio_direction_output\n"); break; case 3: printk("gpio_free\n"); break; default: printk("unknown ioctl cmd!\n"); 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\n"); 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!\n"); return ret; } printk("func: %s\n", __func__); return 0; } static int vib_remove(struct platform_device *pdev) { printk("[ vib_remove] vib_mod_init\n"); return 0; } static void vib_shutdown(struct platform_device *pdev) { printk("[vib_shutdown] vib_mod_init\n"); } /****************************************************************************** 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\n"); ret = platform_device_register(&vibrator_device); if (ret != 0) { printk("[vibrator]Unable to register vibrator device (%d)\n", ret); eturn ret; } ret = platform_driver_register(&vibrator_driver); if (ret) { printk("[vibrator]Unable to register vibrator driver (%d)\n", 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\n"); } 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
cameravibrator设备节点已经创建,权限属于Root权限,在下一篇介绍如何得到全部权限