本帖最后由 carlinluo 于 2015-8-25 17:27 编辑
驱动
#include <dt-bindings/gpio/gpio.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.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/device.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
static struct UserData{
int gpio;
int state;
};
static struct of_device_id luobogpio_of_match[] = {
{ .compatible = "luobogpio" },
{ }
};
MODULE_DEVICE_TABLE(of, luobogpio_of_match);
static int luobogpio_open(struct inode *inode, struct file *filp)
{
printk("luobogpio_open\n");
return 0;
}
static ssize_t luobogpio_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);
}
static long luobogpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long ret = 0;
struct UserData userdata;
unsigned char label[10];
printk("luobogpio_ioctl: cmd = %d arg = %ld\n",cmd, arg);
switch (cmd){
case 0:
printk("gpio_request\n");
if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData)))
return -EFAULT;
printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state);
sprintf(label,"gpio-%d",userdata.gpio);
printk("----->%s\n",label);
ret = gpio_request(userdata.gpio, label);
if (ret) {
printk("failed to request GPIO%d for you ret:%d\n",userdata.gpio,ret);
}
break;
case 1:
printk("gpio_direction_output\n");
if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData)))
return -EFAULT;
printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state);
ret=gpio_direction_output(userdata.gpio, userdata.state);
if (ret) {
printk("failed to gpio_direction_output for you ret:%d\n",userdata.gpio);
}
break;
case 5:
printk("gpio_free\n");
if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData)))
return -EFAULT;
printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state);
gpio_free(userdata.gpio);
break;
default:
printk("unknown ioctl cmd!\n");
ret = -EINVAL;
break;
}
return ret;
}
static int luobogpio_release(struct inode *inode, struct file *filp)
{
printk("luobogpio_release\n");
return 0;
}
static struct file_operations luobogpio_fops = {
.owner = THIS_MODULE,
.open = luobogpio_open,
.read = luobogpio_read,
.unlocked_ioctl = luobogpio_ioctl,
.release = luobogpio_release,
};
static struct miscdevice luobogpio_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "luobogpio",
.fops = &luobogpio_fops,
};
static int luobogpio_probe(struct platform_device *pdev)
{
int ret=-1;
ret = misc_register(&luobogpio_dev);
if (ret < 0){
printk("ac_usb_switch register err!\n");
return ret;
}
printk("func: %s\n", __func__);
return 0;
}
static int luobogpio_remove(struct platform_device *pdev)
{
//printk("func: %s\n", __func__);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int luobogpio_suspend(struct device *dev)
{
//printk("func: %s\n", __func__);
return 0;
}
static int luobogpio_resume(struct device *dev)
{
//printk("func: %s\n", __func__);
return 0;
}
#endif
static const struct dev_pm_ops luobogpio_pm_ops = {
#ifdef CONFIG_PM_SLEEP
.suspend = luobogpio_suspend,
.resume = luobogpio_resume,
.poweroff = luobogpio_suspend,
.restore = luobogpio_resume,
#endif
};
static struct platform_driver luogpio_driver = {
.driver = {
.name = "luobogpio",
.owner = THIS_MODULE,
.pm = &luobogpio_pm_ops,
.of_match_table = of_match_ptr(luobogpio_of_match),
},
.probe = luobogpio_probe,
.remove = luobogpio_remove,
};
module_platform_driver(luogpio_driver);
MODULE_DESCRIPTION("luobogpio Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:luobogpio");
JNI
static jint getGpio(JNIEnv *env, jobject thiz,jint num){
jint ret=-1;
UserData userdata;
memset(&userdata,0x00, sizeof(UserData));
//strlcpy(userdata.name, "gpio",10);
userdata.gpio=num;
userdata.state=0;
ret = ioctl(fd, CMD_GET_GPIO, &userdata);
return ret;
}
static jint releaseGpio(JNIEnv *env, jobject thiz,jint num){
jint ret=-1;
UserData userdata;
memset(&userdata,0x00, sizeof(UserData));
userdata.gpio=num;
userdata.state=0;
ret = ioctl(fd, CMD_RELEASE_GPIO, &userdata);
return ret;
}
static jint openGpioDev(JNIEnv *env, jobject thiz){
jint ret=0;
fd = open("/dev/luobogpio", O_RDWR);
if (fd < 0) {
ret=-1;
}
return ret;
}
static jint closeGpioDev(JNIEnv *env, jobject thiz){
jint ret=0;
ret = close(fd);
if (fd < 0) {
ret=-1;
}
return ret;
}
static jint setGpioState(JNIEnv *env, jobject thiz,jint num,jint state) {
jint err=-1;
UserData userdata;
memset(&userdata,0x00, sizeof(UserData));
userdata.gpio=num;
userdata.state=state;
err = ioctl(fd, CMD_SET_GPIO, &userdata);
if(err<0){
err=-1;
}
return err;
}
APP:
public class LuoboHardware {
static {
// The runtime will add "lib" on the front and ".o" on the end of
// the name supplied to loadLibrary.
System.loadLibrary("app");
}
public native int add(int a, int b);
public native int openGpioDev();
public native int closeGpioDev();
public native int getGpio(int num);
public native int releaseGpio(int num);
public native int setGpioState(int num,int state);
}
写了个简单的应用,可以用以下这些方法控制GPIO了,记得控制的时候,先给驱动节点权限,adb root ->adb shell chmod 777 dev/luobogpio
public native int openGpioDev();
public native int closeGpioDev();
public native int getGpio(int num);
public native int releaseGpio(int num);
public native int setGpioState(int num,int state);
