Chinaunix首页 | 论坛 | 博客
  • 博客访问: 659085
  • 博文数量: 205
  • 博客积分: 7891
  • 博客等级: 少将
  • 技术积分: 2168
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-29 13:16
文章分类

全部博文(205)

文章存档

2015年(4)

2014年(5)

2013年(1)

2012年(4)

2011年(51)

2010年(86)

2009年(45)

2008年(9)

分类: LINUX

2011-05-18 23:56:52

adxl345.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/wakelock.h>
#include <linux/ioctl.h>
#include <linux/ctype.h>
#include <linux/timer.h>

#if defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
#endif

#define DRV_NAME            "adxl345"
#define DRIVER_VERSION        "1.0"
#define IRQ                    57
#define I2C_ADDR            0x53

#define DEVID                0x00
#define THRESH_TAP            0x1D
#define OFSX                0x1E
#define OFSY                0x1F
#define OFSZ                0x20
#define DUR                    0x21
#define LATENT                0x22
#define Window                0x23
#define THRESH_ACT            0x24
#define THRESH_INACT        0x25
#define TIME_INACT            0x26
#define ACT_INACT_CTL        0x27
#define THRESH_FF            0x28
#define TIME_FF                0x29
#define TAP_AXES            0x2A
#define ACT_TAP_STATUS        0x2B
#define BW_RATE                0x2C
#define POWER_CTL            0x2D
#define INT_ENABLE            0x2E
#define INT_MAP                0x2F
#define INT_SOURCE            0x30
#define DATA_FORMAT            0x31
#define DATAX0                0x32
#define DATAX1                0x33
#define DATAY0                0x34
#define DATAY1                0x35
#define DATAZ0                0x36
#define DATAZ1                0x37
#define FIFO_CTL            0x38
#define FIFO_STATUS            0x39

#define THRESH_TAP_VAL        0x50
#define DUR_VAL                0x40
#define LATENT_VAL            0x20
#define Window_VAL            0xF0
#define THRESH_ACT_VAL        1
#define THRESH_INACT_VAL    4
#define TIME_INACT_VAL        1
#define ACT_INACT_CTL_VAL    0xF0
#define THRESH_FF_VAL        8
#define TIME_FF_VAL            0x20
#define TAP_AXES_VAL        0x00
#define BW_RATE_VAL            0x09 // 0x0A

#define POWER_CTL_VAL        0x0B
#define INT_ENABLE_VAL        0x80
#define INT_MAP_VAL            0x00
#define DATA_FORMAT_VAL        0x0B
#define FIFO_CTL_VAL        0x00
#define DELAY            3*HZ

static struct wake_lock gsensor_wake_lock;

struct adxl345_data {
    struct i2c_client *client;
    struct input_dev *input_dev;
    struct mutex lock;
    struct mutex wlock;
    int enable;
    int running;
    int wakelock;    

    struct work_struct work;
    struct work_struct watch_work;

#if defined(CONFIG_HAS_EARLYSUSPEND)
    struct early_suspend early_suspend;
#endif

    u32    irq; /* IRQ number */
    s16 x;
    s16 y;
    s16 z;
};

static struct i2c_adapter *this_adapter;
static struct i2c_client *this_client;
static struct adxl345_data * this_data;
static struct timer_list watch_timer;
static int live = 0;

static int adxl345_i2c_write(struct i2c_client *client,
        u8 reg, u8 val)
{
    struct adxl345_data *data = i2c_get_clientdata(client);
    int ret = 0;

    mutex_lock(&data->lock);

    ret = i2c_smbus_write_byte_data(client, reg, val);

    mutex_unlock(&data->lock);
    return ret;
}

static int adxl345_i2c_read_block(struct i2c_client *client,
         u8 addr, u8 *buf, int len)
{
     struct i2c_msg msgs[2];
 
     msgs[0].addr = client->addr;
     msgs[0].flags = 0;
     msgs[0].len = 1;
     msgs[0].buf = &addr;
 
     msgs[1].addr = client->addr;
     msgs[1].flags = I2C_M_RD;
     msgs[1].len = len;
     msgs[1].buf = buf;
 
     if (i2c_transfer(client->adapter, msgs, 2) < 0) {
         pr_err("%s:i2c_transfer failed!\n", __func__);
         return -EIO;
     }
 
     return 0;
}


static irqreturn_t gs_irq(int irq, void *dev_id)
{
    struct adxl345_data *data = (struct adxl345_data *)dev_id;
    if (data == NULL){
        pr_err("%s:get data failed!!!!!", __func__);
    }
    live = 1;

    schedule_work(&data->work);

    return IRQ_HANDLED;
}

static void work_func(struct work_struct *work)
{
    struct adxl345_data *data = container_of(work, struct adxl345_data, work);
    
    u8 buf[6];
    u8 source;

    source = i2c_smbus_read_byte_data(data->client, INT_SOURCE);
    
    adxl345_i2c_read_block(data->client, DATAX0, buf, 6);
    data->x = (buf[1] << 8) | buf[0];
    data->y = (buf[3] << 8) | buf[2];
    data->z = (buf[5] << 8) | buf[4];

    input_report_abs(data->input_dev, ABS_X, -(data->x));
    input_report_abs(data->input_dev, ABS_Y, data->y);
    input_report_abs(data->input_dev, ABS_Z, data->z);

    input_sync(data->input_dev);

}

static int adxl345_init_reg(struct i2c_client *client)
{
    int ret = 0;
    ret = adxl345_i2c_write(client, BW_RATE, BW_RATE_VAL);
    ret = adxl345_i2c_write(client, DATA_FORMAT, DATA_FORMAT_VAL);
    ret = adxl345_i2c_write(client, FIFO_CTL, FIFO_CTL_VAL);

    ret = adxl345_i2c_write(client, INT_ENABLE, INT_ENABLE_VAL);
    ret = adxl345_i2c_write(client, POWER_CTL, POWER_CTL_VAL);

    return ret;
}

static void watch_work_func(struct work_struct *work)
{
    adxl345_i2c_write(this_data->client, POWER_CTL, 0x07);
    msleep(10);
    adxl345_init_reg(this_data->client);
    printk("gsensor %s\n",__func__);
}

static int adxl345_open(struct input_dev *dev)
{
    /*
    struct adxl345_data * data=input_get_drvdata(dev);
    u8 buf[6], int_s;

    adxl345_init_reg(data->client);
    int_s = i2c_smbus_read_byte_data(data->client, INT_SOURCE);
    adxl345_i2c_read_block(data->client, DATAX0, &buf, 6);
    enable_irq(data->irq);
    */

    return 0;
}
static void adxl345_close(struct input_dev *dev)
{
    /*
    struct adxl345_data * data=input_get_drvdata(dev);


    disable_irq_nosync(data->irq);
    adxl345_i2c_write( data->client, POWER_CTL, 0x07);
    */

    return ;
}
#ifdef CONFIG_PM
static int adxl345_suspend(struct i2c_client *client, pm_message_t state)
{
    del_timer_sync(&watch_timer);
    /*
    printk("hujl@debug:%s enter suspend!\n", __func__);
    struct adxl345_data *data = i2c_get_clientdata(client);
    struct input_dev *input_dev =data->input_dev;
    
    mutex_lock(&input_dev->mutex);
    if(input_dev->users)
    {    
        disable_irq_nosync(data->irq);
        adxl345_i2c_write(client, POWER_CTL, 0x07);
    }
    mutex_unlock(&input_dev->mutex);
    */

    return 0;
}

static int adxl345_resume(struct i2c_client *client)
{
    /*
    printk("hujl@debug:%s enter resume!\n", __func__);
    u8 buf[6], int_s;
    struct adxl345_data *data = i2c_get_clientdata(client);
    struct input_dev *input_dev =data->input_dev;
    
    mutex_lock(&input_dev->mutex);
    if(input_dev->users)
    {    

        adxl345_init_reg(data->client);
        int_s = i2c_smbus_read_byte_data(data->client, INT_SOURCE);
        adxl345_i2c_read_block(client, DATAX0, &buf, 6);
        enable_irq(data->irq);
    }
    mutex_unlock(&input_dev->mutex);
    */

    return 0;
}


#ifdef CONFIG_HAS_EARLYSUSPEND
static void adxl345_early_suspend(struct early_suspend *h)
{
    struct adxl345_data *data = container_of(h, struct adxl345_data, early_suspend);
    adxl345_suspend(data->client, PMSG_SUSPEND);
}

static void adxl345_late_resume(struct early_suspend *h)
{
    struct adxl345_data *data = container_of(h, struct adxl345_data, early_suspend);
    adxl345_resume(data->client);
}
#endif

#else

#define adxl345_suspend NULL
#define adxl345_resume NULL
#endif

static ssize_t gsensor_enable_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t size)
{
    ssize_t ret = -EINVAL;
        char *after;
    int int_s;
        unsigned long state = simple_strtoul(buf, &after, 10);
        size_t count = after - buf;
    u8 tbuf[6];

    printk("%s %s\n",__func__,buf);

        if (*after && isspace(*after))
                count++;

        if (count == size) {
        ret=count;

        if(state>0)
        {
                
            mutex_lock(&this_data->wlock);
        //    this_data->enable++;

            if(this_data->enable==0)
            {    
                    this_data->enable=1;
                adxl345_init_reg(this_data->client);
                int_s = i2c_smbus_read_byte_data(this_data->client, INT_SOURCE);
                adxl345_i2c_read_block(this_data->client, DATAX0, tbuf, 6);
                enable_irq(this_data->irq);
                watch_timer.expires=jiffies + DELAY;
             watch_timer.data = 1;
             add_timer(&watch_timer);
            
            }
            mutex_unlock(&this_data->wlock);
        }
        else
        if(state==0)
        {
            mutex_lock(&this_data->wlock);
            if(this_data->enable>0)
            {
            //    this_data->enable--;

                this_data->enable=0;
                {    
                        disable_irq_nosync(this_data->irq);
                    adxl345_i2c_write(this_data->client, POWER_CTL, 0x07);

                }    
             watch_timer.data = 0;
             del_timer_sync(&watch_timer);
            }
            mutex_unlock(&this_data->wlock);
        }
        }

        return ret;


}
static ssize_t gsensor_enable_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
        return sprintf(buf, "%d\n", this_data->enable);
}

static ssize_t gsensor_wakelock_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t size)
{
    ssize_t ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
        size_t count = after - buf;

    printk("%s %s\n",__func__,buf);

        if (*after && isspace(*after))
                count++;

        if (count == size) {
                ret = count;
        if(state>0)
        {
                
            mutex_lock(&this_data->wlock);
            if(this_data->wakelock==0)
            {
                this_data->wakelock=1;
                wake_lock(&gsensor_wake_lock);
            }
            mutex_unlock(&this_data->wlock);
        }
        else
        if(state==0)
        {
            mutex_lock(&this_data->wlock);
            if(this_data->wakelock==1)
            {
                this_data->wakelock=0;    
                wake_unlock(&gsensor_wake_lock);
            }
            mutex_unlock(&this_data->wlock);
        }
        }
        return ret;

}
static ssize_t gsensor_wakelock_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
        return sprintf(buf, "%d\n",this_data->wakelock);
}

static DEVICE_ATTR(wakelock, 0666, gsensor_wakelock_show, gsensor_wakelock_store);
static DEVICE_ATTR(enable, 0666, gsensor_enable_show, gsensor_enable_store);

void watch_timer_function(unsigned long arg)
{
    int add = arg;

    if((this_data->enable == 1) && (live == 0))
        schedule_work(&this_data->watch_work);
    live = 0;
    if(add == 1)
    {
        watch_timer.expires = jiffies + DELAY;
     add_timer(&watch_timer);
    }
//    printk("%s:\n", __func__);


    return;
}

void watch_timer_init(void)
{
    init_timer(&watch_timer);
    watch_timer.function = watch_timer_function;
    watch_timer.expires = jiffies + DELAY;
    watch_timer.data = 0;
}

static int adxl345_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
    int err = 0;
    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
    struct adxl345_data *data;
    int status;

    printk("%s:\n", __func__);
    if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
        return -EIO;

    data = kzalloc(sizeof(struct adxl345_data), GFP_KERNEL);
    if (!data) {
        pr_err("%s:get memory failed!\n", __func__);
        return -ENOMEM;
    }
    data->client = client;
    i2c_set_clientdata(client, data);
    mutex_init(&data->lock);
    mutex_init(&data->wlock);

    data->input_dev = input_allocate_device();
    if (!data->input_dev) {
        pr_err("%s:input device allocate failed!\n", __func__);
        goto err_free;
    }
    
    data->input_dev->name = "g-sensor";
    data->input_dev->id.bustype = BUS_I2C;

    data->input_dev->close=adxl345_close;
    data->input_dev->open =adxl345_open;

    input_set_drvdata(data->input_dev, data);

    data->input_dev->evbit[0] = BIT_MASK(EV_ABS);
    data->input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) |
                                BIT(ABS_Z);

    input_set_abs_params(data->input_dev, ABS_X, -32767, 32767, 0, 0);    
    input_set_abs_params(data->input_dev, ABS_Y, -32767, 32767, 0, 0);    
    input_set_abs_params(data->input_dev, ABS_Z, -32767, 32767, 0, 0);    
        
    err = input_register_device(data->input_dev);
    if (err){
        pr_err("%s: Cannot register input (%d)\n", __func__, err);
        goto err_free_inputdev;
    }

    INIT_WORK(&data->work, work_func);
    INIT_WORK(&data->watch_work, watch_work_func);
    this_data = data;

    err = gpio_request(IRQ, "adxl345_irq");
    if (err) {
         pr_err("request_gpio failed! err = %d\n", err);
         goto err_unregister_input_dev;
     }

    gpio_tlmm_config(GPIO_CFG(IRQ, 0, GPIO_INPUT,
                             GPIO_PULL_DOWN, GPIO_8MA), GPIO_ENABLE);
    
    data->irq = MSM_GPIO_TO_INT(IRQ);
    err = request_irq(data->irq, gs_irq, IRQF_TRIGGER_RISING, "adxl345", data);
    if (err){
        pr_err("request irq failed! err = %d\n", err);
        goto err_free_gpio;
    }
    disable_irq_nosync(data->irq);
    /*
    err = adxl345_init_reg(client);
    if (err) {
        pr_err("init registers failed! err = %d\n", err);
        goto err_free_irq;
    }
    */


#ifdef CONFIG_HAS_EARLYSUSPEND
    data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
    data->early_suspend.suspend = adxl345_early_suspend;
    data->early_suspend.resume = adxl345_late_resume;
    register_early_suspend(&data->early_suspend);
#endif

    dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
    status=device_create_file(&data->input_dev->dev ,&dev_attr_enable);
    if(status)
    {
        goto err_free_irq;

    }
    status=device_create_file(&data->input_dev->dev ,&dev_attr_wakelock);
    if(status)
    {
        device_remove_file(&data->input_dev->dev ,&dev_attr_enable);
        goto err_free_irq;
    }
    wake_lock_init(&gsensor_wake_lock, WAKE_LOCK_SUSPEND, "gsensor");
    watch_timer_init();

    return 0;

err_free_irq:
#ifdef CONFIG_HAS_EARLYSUSPEND
    unregister_early_suspend(&data->early_suspend);
#endif

    free_irq(data->irq, data);
err_free_gpio:
    gpio_free(IRQ);
err_unregister_input_dev:
    input_unregister_device(data->input_dev);
err_free_inputdev:
    input_free_device(data->input_dev);
err_free:
    kfree(data);
    return err;
}

static int __devexit adxl345_remove(struct i2c_client *client)
{
    struct adxl345_data *data = i2c_get_clientdata(client);

    wake_lock_destroy(&gsensor_wake_lock);

#ifdef CONFIG_HAS_EARLYSUSPEND
    unregister_early_suspend(&data->early_suspend);
#endif

    free_irq(data->irq, data);
    gpio_free(IRQ);
    cancel_work_sync(&data->work);
    input_unregister_device(data->input_dev);
    this_data=NULL;

    kfree(data);

    return 0;
}

static const struct i2c_device_id adxl345_id[] = {
    {"adxl345", 0},
    {}
};
MODULE_DEVICE_TABLE(i2c, adxl345_id);

static struct i2c_driver adxl345_driver = {
    .driver = {
        .name    = DRV_NAME,
        .owner    = THIS_MODULE,
    },
    .probe    = adxl345_probe,
    .remove    = adxl345_remove,
    .id_table = adxl345_id,
#ifndef CONFIG_HAS_EARLYSUSPEND
    .suspend = adxl345_suspend,
    .resume = adxl345_resume,
#endif
};

static int __init adxl345_init(void)
{
    struct i2c_board_info info[]= {
        { I2C_BOARD_INFO("adxl345", I2C_ADDR), },
    };

    printk("%s:\n", __func__);

    this_adapter = i2c_get_adapter(0);
    if (!this_adapter) {
        printk("%s: i2c_get_adapter failed\n", __func__);
        return PTR_ERR(this_adapter);
    }

    this_client = i2c_new_device(this_adapter, info);
    if (!this_client) {
        printk("%s: i2c_new_device failed\n", __func__);
        return PTR_ERR(this_client);
    } else {
        this_client->adapter = this_adapter;
        printk("%s: this_client = 0x%p \n", __func__, this_client);
    }
    return i2c_add_driver(&adxl345_driver);
}

static void __exit adxl345_exit(void)
{
    i2c_del_driver(&adxl345_driver);
    i2c_unregister_device(this_client);
}

MODULE_AUTHOR("Gening.Hu ");
MODULE_DESCRIPTION("adxl345");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(DRIVER_VERSION);

module_init(adxl345_init);
module_exit(adxl345_exit);

sensor.cpp


#define LOG_TAG "SensorHal"

#include <hardware/hardware.h>
#include <hardware/sensors.h>

#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include <poll.h>
#include <linux/input.h>
#include <utils/Log.h>
#include <cutils/atomic.h>

#define LSG (720.0f)

#define CONVERT_A 1
#define CONVERT_A_X (CONVERT_A)
#define CONVERT_A_Y (-CONVERT_A)
#define CONVERT_A_Z (CONVERT_A)

#define COUNT 24

struct sensors_control_context_t {
    struct sensors_control_device_t device;
    /* our private state goes below here */
};

struct sensors_data_context_t {
    struct sensors_data_device_t device;
    /* our private state goes below here */
};

static int sensors_device_open(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device);

static struct hw_module_methods_t sensors_module_methods = {
    open: sensors_device_open
};

static struct sensor_t const sensor_mma7660 = {
    name: "mma7660",
    vendor: "FSL",
    version: 2,
    handle: SENSORS_HANDLE_BASE + 1,
    type: SENSOR_TYPE_ACCELEROMETER,
    maxRange: 1023,
    resolution: 2,
};

struct sensor_handle_t : public native_handle {
    /* add the data fields we need here, for instance: */
    int ctl_fd;
};

sensor_handle_t sensor_data_handle;

static int get_sensors_list(struct sensors_module_t* module, struct sensor_t const** sensor)
{
    *sensor = &sensor_mma7660;

    LOGD("sensor name %s, handle %d, type %d\n",
        (*sensor)->name, (*sensor)->handle, (*sensor)->type);

    return 1;
}

struct sensors_module_t HAL_MODULE_INFO_SYM = {
    common : {
        tag : HARDWARE_MODULE_TAG,
        version_major : 1,
        version_minor : 0,
        id : SENSORS_HARDWARE_MODULE_ID,
        name : "Sonsor module",
        author : "BTG at thunderst",
        methods : &sensors_module_methods,
    },
    get_sensors_list : get_sensors_list,
};

static int open_input()
{
    /* scan all input drivers and look for "mma7660" */
    int fd = -1;
    const char *dirname = "/dev/input";
    char devname[PATH_MAX];
    char *filename;
    DIR *dir;
    struct dirent *de;
    dir = opendir(dirname);
    if(dir == NULL)
        return -1;
    strcpy(devname, dirname);
    filename = devname + strlen(devname);
    *filename++ = '/';
    while((de = readdir(dir))) {
        if(de->d_name[0] == '.' &&
           (de->d_name[1] == '\0' ||
            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
            continue;
        strcpy(filename, de->d_name);
        fd = open(devname, O_RDONLY);
        if (fd>=0) {
            char name[80];
            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
                name[0] = '\0';
            }
                LOGD("name %s\n", name);
            if (!strcmp(name, "mma7660")) {
                LOGD("using %s (name=%s)\n", devname, name);
                break;
            }
            close(fd);
            fd = -1;
        }
    }
    closedir(dir);

    if (fd < 0) {
        LOGE("Couldn't find or open 'mma7660' driver (%s)\n", strerror(errno));
    }
    return fd;
}

static native_handle_t* open_data_source(struct sensors_control_device_t *dev)
{
    LOGD("enter open_data_source!\n");
    memset(&sensor_data_handle, 0, sizeof(sensor_data_handle));
    sensor_data_handle.numFds = 1;
    sensor_data_handle.numInts = 0; // extra ints we have in our handle

    sensor_data_handle.ctl_fd = open_input();

    return &sensor_data_handle;
}

static int activate(struct sensors_control_device_t *dev, int handle, int enabled)
{
    LOGD("active handle %d\n",handle);

    if (handle != sensor_mma7660.handle)
     return -1;

    return sensor_mma7660.handle;
}

static int set_delay(struct sensors_control_device_t *dev, int32_t ms)
{
    LOGD("set delay %d ms\n",ms);
    return 0;
}

static int wake(struct sensors_control_device_t *dev)
{
    LOGD("sensor wake\n");
    return 0;
}

static int sInputFD = -1;
static sensors_data_t sSensors;

static int data_open(struct sensors_data_device_t *dev, native_handle_t* nh)
{
    int i;
    int fd;
    fd = ((sensor_handle_t *)nh)->ctl_fd;
    LOGD("sensor data open FD %d\n",fd);
    memset(&sSensors, 0, sizeof(sSensors));
    sSensors.vector.status = SENSOR_STATUS_ACCURACY_HIGH;

    sInputFD = dup(fd);

    LOGD("sensors_data_open: fd = %d\n", sInputFD);
    return 0;
}

static int data_close(struct sensors_data_device_t *dev)
{
    LOGD("sensor data close\n");
    close(sInputFD);
    return 0;
}

static int sensor_poll(struct sensors_data_device_t *dev, sensors_data_t* data)
{
    LOGD("enter sensor_poll\n");
    struct input_event event;
    int64_t t;
    int nread;

    int fd = sInputFD;

    if (fd <= 0)
        return -1;

    while (1) {
        nread = read(fd, &event, sizeof(event));

        if (nread == sizeof(event)) {
               uint32_t v;
            if (event.type == EV_ABS) {
                   switch (event.code) {
                    case ABS_X:
                            sSensors.acceleration.x = event.value * CONVERT_A_X;break;
                    case ABS_Y:
                            sSensors.acceleration.y = event.value * CONVERT_A_Y;break;
                    case ABS_Z:
                            sSensors.acceleration.z = event.value * CONVERT_A_Z;break;
                }
            } else if (event.type == EV_SYN) {
                *data = sSensors;

                return SENSORS_HANDLE_BASE + 1;

            }
        }
    }
}

static int sensors_device_control_close(struct hw_device_t *dev)
{
    LOGD("enter sensors_device_control_close!\n");
    struct sensors_control_context_t* ctx = (struct sensors_control_context_t*)dev;
    if (ctx) {
        /* free all resources associated with this device here
         * in particular the sensors_handle_t, outstanding sensors_t, etc...
         */

        free(ctx);
    }
    return 0;
}

static int sensors_device_data_close(struct hw_device_t *dev)
{
    LOGD("enter sensors_device_data_close!\n");
    struct sensors_data_context_t* ctx = (struct sensors_data_context_t*)dev;
    if (ctx) {
        /* free all resources associated with this device here
         * in particular all pending sensors_buffer_t if needed.
         *
         * NOTE: sensors_handle_t passed in initialize() is NOT freed and
         * its file descriptors are not closed (this is the responsibility
         * of the caller).
         */

        free(ctx);
    }
    return 0;
}

static int sensors_device_open(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device)
{
    int status = -EINVAL;

    LOGD("sensor device open %s\n", name);
    if (!strcmp(name, SENSORS_HARDWARE_CONTROL)) {
        struct sensors_control_context_t *dev;
        dev = (struct sensors_control_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = sensors_device_control_close;
        
        dev->device.open_data_source = open_data_source;
        dev->device.activate = activate;
        dev->device.set_delay = set_delay;
        dev->device.wake = wake;

        *device = &dev->device.common;
        status = 0;
    } else if (!strcmp(name, SENSORS_HARDWARE_DATA)) {
        struct sensors_data_context_t *dev;
        dev = (struct sensors_data_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = sensors_device_data_close;
        
        dev->device.data_open = data_open;
        dev->device.data_close = data_close;
        dev->device.poll = sensor_poll;
        
        *device = &dev->device.common;
        status = 0;
    }
    return status;
}


阅读(1983) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~