android实现开机闪关灯闪一下功能

1在soul45-dint/mediatek/kernel/drivers/下新建一个目录flash_led

目录下放.C文件和Makefile文件

新建flash_led.c makefile

 flash_led.h代码如下:


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/time.h>
#include "kd_flashlight.h"
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include "kd_camera_hw.h"


#define USE_UNLOCKED_IOCTL


/******************************************************************************
 * Definition
******************************************************************************/
#ifndef TRUE
#define TRUE KAL_TRUE
#endif
#ifndef FALSE
#define FALSE KAL_FALSE
#endif


/* device name and major number */
#define FLASHLIGHT_DEVNAME            "flash_led"// this is the dev/name


#define DELAY_MS(ms) {mdelay(ms);}//unit: ms(10^-3)
#define DELAY_US(us) {mdelay(us);}//unit: us(10^-6)
#define DELAY_NS(ns) {mdelay(ns);}//unit: ns(10^-9)


/******************************************************************************
 * Debug configuration
******************************************************************************/
#define PFX "[FLASH_LED]"
#define PK_DBG_NONE(fmt, arg...)    do {} while (0)
#define PK_DBG_FUNC(fmt, arg...)    printk(KERN_INFO PFX "flash_led_test %s: " fmt, __FUNCTION__ ,##arg)


#define PK_WARN(fmt, arg...)        printk(KERN_WARNING PFX "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_NOTICE(fmt, arg...)      printk(KERN_NOTICE PFX "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_INFO(fmt, arg...)        printk(KERN_INFO PFX "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_TRC_FUNC(f)              printk(PFX "<%s>\n", __FUNCTION__);
#define PK_TRC_VERBOSE(fmt, arg...) printk(PFX fmt, ##arg)


#define DEBUG_FLASH_LED
#ifdef DEBUG_FLASH_LED
#define PK_DBG PK_DBG_FUNC
#define PK_TRC PK_DBG_NONE //PK_TRC_FUNC
#define PK_VER PK_DBG_NONE //PK_TRC_VERBOSE
#define PK_ERR(fmt, arg...)         printk(KERN_ERR PFX "%s: " fmt, __FUNCTION__ ,##arg)
#else
#define PK_DBG(a,...)
#define PK_TRC(a,...)
#define PK_VER(a,...)
#define PK_ERR(a,...)
#endif
/*****************************************************************************


*****************************************************************************/


#define FLASH_GPIO_ENABLE GPIO12  //enble pin 
#define FLASH_GPIO_FLASH GPIO13  //flash pin
static int flash_led_state=0;  //flash_led_state
static struct task_struct * flash_thread_id = NULL;


/******************************************************************/
//gpio control 
//******************************************************************/




int FLASH_LED_Enable(void)
{
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ONE);
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ZERO);
PK_DBG(" FLASH_LED_Enable line=%d\n",__LINE__);


    return 0;
}






int FLASH_LED_Disable(void)
{

mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ZERO);
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ZERO);
PK_DBG(" FLASH_LED_Disable line=%d\n",__LINE__);
    return 0;
}






int FLASH_LED_Init(void)
{
    if(mt_set_gpio_mode(FLASH_GPIO_FLASH,GPIO_MODE_00)){PK_DBG("[flash_led] set gpio mode failed!! \n");}
    if(mt_set_gpio_dir(FLASH_GPIO_FLASH,GPIO_DIR_OUT)){PK_DBG("[flash_led] set gpio dir failed!! \n");}
    if(mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ONE)){PK_DBG("[flash_led] set gpio failed!! \n");}


    if(mt_set_gpio_mode(FLASH_GPIO_ENABLE,GPIO_MODE_00)){PK_DBG("[flash_led] set gpio mode failed!! \n");}
    if(mt_set_gpio_dir(FLASH_GPIO_ENABLE,GPIO_DIR_OUT)){PK_DBG("[flash_led] set gpio dir failed!! \n");}
    if(mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ONE)){PK_DBG("[flash_led] set gpio failed!! \n");}
    PK_DBG(" FLASH_LED_Uninit line=%d\n",__LINE__);




    return 0;
}




int FLASH_LED_Uninit(void)
{
FLASH_LED_Disable();
PK_DBG(" FLASH_LED_Uninit line=%d\n",__LINE__);
    return 0;
}
/***********************************************************************************/
/***********************************************************************************/


/*show the  flash pin and enable pin state
*example:cat flash_led state
*/
static ssize_t flash_led_state_show(struct device *dev,struct device_attribute *attr,char *buf)
{
/* addby limin.zhuo.hz at 2014.11.12 */
PK_DBG(" FLASH_STATUS =%d, \n", flash_led_state);
return sprintf(buf, "%u\n",flash_led_state);
}


static int flash_thread(void* arg) {
while (1) {
if (kthread_should_stop()) break;
FLASH_LED_Enable();
msleep(10);
FLASH_LED_Disable();
msleep(1000);
}
}
static ssize_t flash_led_state_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{
//zhe li  shi  xian 4  5 yao qiu 
// add by limin.zhuo.hz at 2014.11.12
int err;
if (count <= 0) {
PK_ERR("flash_led_state_store error");
  return 0;
}
unsigned int value = 0;
sscanf(buf, "%d", &value);
PK_DBG(" FLASH_VALUE =%d, \n", value);
switch (value) {
case 0:
FLASH_LED_Disable();
flash_led_state=0;
break;
case 1:
FLASH_LED_Enable();
flash_led_state=1;
break;
case 2:
// creat thread
flash_thread_id = kthread_create(flash_thread, NULL, "flash_thread");
if (IS_ERR(flash_thread_id)) {
PK_ERR("flash_thread create failed");
err = PTR_ERR(flash_thread_id);
flash_thread_id = NULL;
return err;
}
wake_up_process(flash_thread_id);
        flash_led_state=1;
break;
case 3:
// stop thread
if (flash_thread_id ) {
kthread_stop(flash_thread_id);
flash_thread_id = NULL;
}
        flash_led_state=0;
break;

default:
FLASH_LED_Disable();
        flash_led_state=0;

}
return strnlen(buf, count);
}


/*control the flash_led state
*example:echo 0 1  > flash_led state
*/
static DEVICE_ATTR(flash_led_state, 0666, flash_led_state_show,
flash_led_state_store);






/****************************************************************************************************************/


/****************************************************************************************************************/
#ifdef USE_UNLOCKED_IOCTL
static long flashlight_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#else
static int flashlight_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
#endif
{


    int i4RetValue = 0;


    PK_DBG("XXflashlight_ioctl cmd,arg= %x, %x +\n",cmd,(unsigned int)arg);
    switch (cmd)
{
case 0:
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ZERO);// 真正对硬件的操作,把管脚设置为高低电平
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ZERO);
flash_led_state=0;
break;
case 1:
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ONE);
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ONE);
flash_led_state=1;
break;
case 2:
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ZERO);
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ONE);
        flash_led_state=0;
break;
case 3:
if (flash_thread_id) {
kthread_stop(flash_thread_id);
flash_thread_id = NULL;
}
        flash_led_state=0;
break;

default:
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ZERO);
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ZERO);
        flash_led_state=0;
}


   return i4RetValue;
}


static int flashlight_open(struct inode *inode, struct file *file)
{
    int i4RetValue = 0;
    PK_DBG("[flashlight_open] E\n");
 //   FLASH_LED_Init();
    return i4RetValue;
}


static int flashlight_release(struct inode *inode, struct file *file)
{
    PK_DBG("[flashlight_release] E\n");
    FLASH_LED_Disable();
   


    return 0;
}


/*****************************************************************************/
/* Kernel interface */
static struct file_operations flashlight_fops = {
    .owner      = THIS_MODULE,
#ifdef USE_UNLOCKED_IOCTL
    .unlocked_ioctl      = flashlight_ioctl,
#else
    .ioctl      = flashlight_ioctl,
#endif
    .open       = flashlight_open,
    .release    = flashlight_release,
};


/*****************************************************************************
Driver interface
*****************************************************************************/


static struct class *flashlight_class = NULL; // 节点类
static struct device *flashlight_device = NULL; // 节点设备
static dev_t flashlight_devno;  // 设备号
static struct cdev flashlight_cdev;
/****************************************************************************/
#define ALLOC_DEVNO
static int flashlight_probe(struct platform_device *dev)
{
    int ret = 0, err = 0;


PK_DBG("[flashlight_probe] start\n");


#ifdef ALLOC_DEVNO
    ret = alloc_chrdev_region(&flashlight_devno, 0, 1, FLASHLIGHT_DEVNAME);
    if (ret) {
        PK_ERR("[flashlight_probe] alloc_chrdev_region fail: %d\n", ret);
        goto flashlight_probe_error;
    } else {
        PK_DBG("[flashlight_probe] major: %d, minor: %d\n", MAJOR(flashlight_devno), MINOR(flashlight_devno));
    }
    cdev_init(&flashlight_cdev, &flashlight_fops);
    flashlight_cdev.owner = THIS_MODULE;
    err = cdev_add(&flashlight_cdev, flashlight_devno, 1);
    if (err) {
        PK_ERR("[flashlight_probe] cdev_add fail: %d\n", err);
        goto flashlight_probe_error;
    }
// 上面代码会在/dev/flash_led创建一个设备,这个设备是抽象的。
#else
    #define FLASHLIGHT_MAJOR 242
    ret = register_chrdev(FLASHLIGHT_MAJOR, FLASHLIGHT_DEVNAME, &flashlight_fops);
    if (ret != 0) {
        PK_ERR("[flashlight_probe] Unable to register chardev on major=%d (%d)\n", FLASHLIGHT_MAJOR, ret);
        return ret;
    }
    flashlight_devno = MKDEV(FLASHLIGHT_MAJOR, 0);
#endif
// 下面的代码在sys/class/flashdev目录下创建一个文件节点,通过对文件读写操作就会跳转到指定的函数内执行相应的逻辑操作
    //create the class name flashlightdrv
    flashlight_class = class_create(THIS_MODULE, "flashleddrv");
    if (IS_ERR(flashlight_class)) {
        PK_ERR("[flashlight_probe] Unable to create class, err = %d\n", (int)PTR_ERR(flashlight_class));
        goto flashlight_probe_error;
    }
    //create the device name  "flash_led"
    flashlight_device = device_create(flashlight_class, NULL, flashlight_devno, NULL, FLASHLIGHT_DEVNAME);
    if(NULL == flashlight_device){
        PK_ERR("[flashlight_probe] device_create fail\n");
        goto flashlight_probe_error;
    }
   //create the file name  flash_led_state
   if (device_create_file(flashlight_device, &dev_attr_flash_led_state) < 0)
pr_err("Failed to create device file(%s)!\n", dev_attr_flash_led_state.attr.name);


// 开始的时候启动代码一次
   //when booting ,flash once .
FLASH_LED_Init();
msleep(10);
mt_set_gpio_out(FLASH_GPIO_ENABLE,GPIO_OUT_ZERO);// 对应闪光灯的引脚,zero为低电平
mt_set_gpio_out(FLASH_GPIO_FLASH,GPIO_OUT_ZERO);


    PK_DBG("[flashlight_probe] Done\n");
    return 0;


flashlight_probe_error:
#ifdef ALLOC_DEVNO
    if (err == 0)
        cdev_del(&flashlight_cdev);
    if (ret == 0)
        unregister_chrdev_region(flashlight_devno, 1);
#else
    if (ret == 0)
        unregister_chrdev(MAJOR(flashlight_devno), FLASHLIGHT_DEVNAME);
#endif
    return -1;
}


static int flashlight_remove(struct platform_device *dev)
{


    PK_DBG("[flashlight_probe] start\n");


#ifdef ALLOC_DEVNO
    cdev_del(&flashlight_cdev);
    unregister_chrdev_region(flashlight_devno, 1);
#else
    unregister_chrdev(MAJOR(flashlight_devno), FLASHLIGHT_DEVNAME);
#endif
    device_destroy(flashlight_class, flashlight_devno);
    class_destroy(flashlight_class);


    PK_DBG("[flashlight_probe] Done\n");
    return 0;
}




static struct platform_driver flashlight_platform_driver =
{
    .probe      = flashlight_probe,// 加载驱动时调用该方法
    .remove     = flashlight_remove,// 卸载驱动调用该方法
    .driver     = {
        .name = FLASHLIGHT_DEVNAME,// 驱动名,和设备名
.owner = THIS_MODULE,
    },
};


static struct platform_device flashlight_platform_device = {
    .name = FLASHLIGHT_DEVNAME,// 设备名称,该名称必须和驱动名称一致。
    .id = 0,
    .dev = {
    }
};


static int __init flashlight_init(void)
{
    int ret = 0;
    PK_DBG("[flashlight_probe] start\n");
// 注册一个设备
ret = platform_device_register (&flashlight_platform_device);
if (ret) {
        PK_ERR("[flashlight_probe] platform_device_register fail\n");
        return ret;
}
// 注册一个驱动, 通过注册可以设备对应一个驱动,由上层调用。
    ret = platform_driver_register(&flashlight_platform_driver);
if(ret){
PK_ERR("[flashlight_probe] platform_driver_register fail\n");
return ret;
}


PK_DBG("[flashlight_probe] done!\n");
    return ret;
}


static void __exit flashlight_exit(void)
{
    PK_DBG("[flashlight_probe] start\n");
    platform_driver_unregister(&flashlight_platform_driver);
 
    PK_DBG("[flashlight_probe] done!\n");
}


/*****************************************************************************/
/* 代码的执行起点,当内核加载模块时调用flashlight_init, 当卸载模块调用flashlight_exit*/
module_init(flashlight_init);
module_exit(flashlight_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("limin.zhuo <limin.zhuo.hz@tcl.com>");
MODULE_DESCRIPTION("FLAH_LED CONTROL TEST");




makefile文件如下:


obj-y += flash_led.o

 

2/local/sdb/soul45-dint/mediatek/kernel/drivers

在这里的根目录下MAKEFILE文件下添加

obj-y   += flash_led/

 

作用是把flash_led目录下的文件编译进内核

 

3把代码放进去 然后执行./makeMtk-t soul45 r k

编译通过之后

./makeMtk -t soul45 r bootimage

 

4单独烧写bootimage 就行了

在teleweb 的general 下去掉formal userdata

 

全烧写一边也行 时间长

 

5启动 手机

现象:开机闪光

 

6查看节点:

root@SOUL45_GSM:/dev # ll flash_led                                           

crw------- root     root    252,   0 2014-01-01 08:00 flash_led

 

 

**这里的DEV目下下出现了你定义的设备名字

可以通过

root@SOUL45_GSM:/dev # ioctl  flash_led 0                                     

sending ioctl 0x0

root@SOUL45_GSM:/dev # ioctl  flash_led 1                                    

sending ioctl 0x1

 

 

**这里操作对应的文件 就能操作对应的闪光灯实现亮灭

 

利用ioctl 节点名字 cmd

 

他就会根据一系列的响应最终调用驱动代码的

#ifdef USE_UNLOCKED_IOCTL

static longflashlight_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

#else

static intflashlight_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)

 

 

7查看对应的class和devices

root@SOUL45_GSM:/sys/class/flashleddrv # cdflash_led/                        

root@SOUL45_GSM:/sys/class/flashleddrv/flash_led# ls

dev

flash_led_state

power

subsystem

uevent

 

**这里出现了对应的文件节点:

 

可以通过cat flash_led 和echo **操作具体的节点

代码没有写具体过程,大家自己写

 

cat flash_led_state  命令获取闪光灯的状态,0代表关闭闪光,1代表有闪光。

echo number > flash_led_state 把参数写入节点文件。

 

number值如下说明:

0 -----à   关闭闪光灯

1-----à   打开闪光灯

2----à 自动闪光,每隔一秒闪一次

3---à  关闭自动闪光。

 

效果图:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值