mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 13:27:06 +09:00
Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
This commit is contained in:
85
arch/arm/mach-rk29/include/mach/custom_log.h
Executable file
85
arch/arm/mach-rk29/include/mach/custom_log.h
Executable file
@@ -0,0 +1,85 @@
|
||||
/* --------------------------------------------------------------------------------------------------------
|
||||
* Copyright(C), 2010-2011, Fuzhou Rockchip Co., Ltd. All Rights Reserved.
|
||||
*
|
||||
* File: custom_log.h
|
||||
*
|
||||
* Desc: ChenZhen ƫ<>õ<EFBFBD> log <20><><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>ʵ<EFBFBD><CAB5>.
|
||||
*
|
||||
* -----------------------------------------------------------------------------------
|
||||
* < ϰ<><CFB0> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> > :
|
||||
*
|
||||
* -----------------------------------------------------------------------------------
|
||||
*
|
||||
* Usage: <09><><EFBFBD>ñ<EFBFBD> log <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> .c <20>ļ<EFBFBD>, <20><>Ҫʹ<D2AA><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> log <20><><EFBFBD><EFBFBD>,
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> inclue <20><><EFBFBD>ļ<EFBFBD>֮ǰ, "#define ENABLE_DEBUG_LOG" <20><>.
|
||||
* Note:
|
||||
*
|
||||
* Author: ChenZhen
|
||||
*
|
||||
* --------------------------------------------------------------------------------------------------------
|
||||
* Version:
|
||||
* v1.0
|
||||
* --------------------------------------------------------------------------------------------------------
|
||||
* Log:
|
||||
----Fri Nov 19 15:20:28 2010 v1.0
|
||||
*
|
||||
* --------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CUSTOM_LOG_H__
|
||||
#define __CUSTOM_LOG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------
|
||||
* Include Files
|
||||
* ---------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------
|
||||
* Macros Definition
|
||||
* ---------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
#define D(fmt, args...) \
|
||||
{ printk("[File]:%s; [Line]:%d; [Func]:%s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }
|
||||
#else
|
||||
#define D(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#define W(fmt, args...) \
|
||||
{ printk("WARNING :: [File]:%s; [Line]:%d; [Func]:%s() :: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }
|
||||
|
||||
#define E(fmt, args...) \
|
||||
{ printk("ERROR :: [File]:%s; [Line]:%d; [Func]:%s() :: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------
|
||||
* Types and Structures Definition
|
||||
* --------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------
|
||||
* Global Functions' Prototype
|
||||
* ---------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------
|
||||
* Inline Functions Implementation
|
||||
* ---------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUSTOM_LOG_H__ */
|
||||
|
||||
@@ -30,7 +30,7 @@ config GS_MMA8452
|
||||
config GS_L3G4200D
|
||||
bool "gs_l3g4200d"
|
||||
depends on G_SENSOR_DEVICE
|
||||
default y
|
||||
default n
|
||||
help
|
||||
To have support for your specific gsesnor you will have to
|
||||
select the proper drivers which depend on this option.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -32,11 +33,22 @@
|
||||
#include <linux/earlysuspend.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define mmaprintk(x...) printk(x)
|
||||
// #define ENABLE_DEBUG_LOG
|
||||
#include <mach/custom_log.h>
|
||||
|
||||
#if 1
|
||||
#define mmaprintk(x...) D(x)
|
||||
#else
|
||||
#define mmaprintk(x...)
|
||||
#endif
|
||||
|
||||
// #define ENABLE_VERBOSE_LOG
|
||||
#ifdef ENABLE_VERBOSE_LOG
|
||||
#define V(x...) D(x)
|
||||
#else
|
||||
#define V(x...)
|
||||
#endif
|
||||
|
||||
static int mma8452_probe(struct i2c_client *client, const struct i2c_device_id *id);
|
||||
|
||||
#define MMA8452_SPEED 200 * 1000
|
||||
@@ -53,13 +65,48 @@ static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq);
|
||||
static struct early_suspend mma8452_early_suspend;
|
||||
#endif
|
||||
static int revision = -1;
|
||||
static const char* vendor = "Freescale Semiconductor";
|
||||
|
||||
|
||||
typedef char status_t;
|
||||
/*status*/
|
||||
#define MMA8452_OPEN 1
|
||||
#define MMA8452_CLOSE 0
|
||||
|
||||
|
||||
// .! : <20>豸ʵ<E8B1B8><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
struct mma8452_data {
|
||||
status_t status;
|
||||
char curr_tate;
|
||||
struct input_dev *input_dev;
|
||||
struct i2c_client *client;
|
||||
struct work_struct work;
|
||||
struct delayed_work delaywork; /*report second event*/
|
||||
|
||||
/** <20><><EFBFBD><EFBFBD> sensor <20><><EFBFBD><EFBFBD>. */
|
||||
struct mma8452_axis sense_data;
|
||||
/** <20><> "sense_data" <20>Ļ<EFBFBD><C4BB>Ᵽ<EFBFBD><E2B1A3>. */
|
||||
struct mutex sense_data_mutex;
|
||||
|
||||
/** <20><>ʶ "sense_data" <20>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч. */
|
||||
atomic_t data_ready;
|
||||
/** <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD> <20><><EFBFBD><EFBFBD> ready <20>ĵȴ<C4B5><C8B4><EFBFBD><EFBFBD><EFBFBD>ͷ. */
|
||||
wait_queue_head_t data_ready_wq;
|
||||
|
||||
/** <20><>ʶ <20>豸<EFBFBD><E8B1B8>Ҫ<EFBFBD><D2AA> START <20>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ݵĴ<DDB5><C4B4><EFBFBD>, <20><>Ӧ MMA_IOCTL_START <20><><EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD>. */
|
||||
int start_count;
|
||||
/** <20><> 'start_count' <20><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>Ᵽ<EFBFBD><E2B1A3>. */
|
||||
struct mutex operation_mutex;
|
||||
};
|
||||
|
||||
/* AKM HW info */
|
||||
static ssize_t gsensor_vendor_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
sprintf(buf, "%#x\n", revision);
|
||||
// sprintf(buf, "%#x\n", revision);
|
||||
sprintf(buf, "%s.\n", vendor);
|
||||
ret = strlen(buf) + 1;
|
||||
|
||||
return ret;
|
||||
@@ -82,7 +129,7 @@ static int gsensor_sysfs_init(void)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr);
|
||||
ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr); // "vendor"
|
||||
if (ret) {
|
||||
mmaprintk(KERN_ERR
|
||||
"MMA8452 gsensor_sysfs_init:"\
|
||||
@@ -206,7 +253,7 @@ static int mma8452_start_dev(struct i2c_client *client, char rate)
|
||||
{
|
||||
int ret = 0;
|
||||
int tmp;
|
||||
struct mma8452_data *mma8452 = (struct mma8452_data *)i2c_get_clientdata(client);
|
||||
struct mma8452_data *mma8452 = (struct mma8452_data *)i2c_get_clientdata(client); // mma8452_data <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mma8452.h <20><>.
|
||||
|
||||
mmaprintk("-------------------------mma8452 start ------------------------\n");
|
||||
/* standby */
|
||||
@@ -309,11 +356,13 @@ static void mma8452_report_value(struct i2c_client *client, struct mma8452_axis
|
||||
input_report_abs(mma8452->input_dev, ABS_Y, axis->y);
|
||||
input_report_abs(mma8452->input_dev, ABS_Z, axis->z);
|
||||
input_sync(mma8452->input_dev);
|
||||
mmaprintk("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
|
||||
V("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
|
||||
}
|
||||
|
||||
/** <20><> <20>װ벿ִ<EBB2BF><D6B4>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ g sensor <20><><EFBFBD><EFBFBD>. */
|
||||
static int mma8452_get_data(struct i2c_client *client)
|
||||
{
|
||||
struct mma8452_data* mma8452 = i2c_get_clientdata(client);
|
||||
char buffer[6];
|
||||
int ret;
|
||||
struct mma8452_axis axis;
|
||||
@@ -328,7 +377,7 @@ static int mma8452_get_data(struct i2c_client *client)
|
||||
return ret;
|
||||
} while (0);
|
||||
|
||||
mmaprintk("0x%02x 0x%02x 0x%02x \n",buffer[0],buffer[1],buffer[2]);
|
||||
V("0x%02x 0x%02x 0x%02x \n",buffer[0],buffer[1],buffer[2]);
|
||||
|
||||
axis.x = mma8452_convert_to_int(buffer[0]);
|
||||
axis.y = mma8452_convert_to_int(buffer[1]);
|
||||
@@ -340,14 +389,24 @@ static int mma8452_get_data(struct i2c_client *client)
|
||||
swap(axis.x,axis.y);
|
||||
}
|
||||
|
||||
// mmaprintk( "%s: ------------------mma8452_GetData axis = %d %d %d--------------\n",
|
||||
// __func__, axis.x, axis.y, axis.z);
|
||||
V( "%s: ------------------mma8452_GetData axis = %d %d %d--------------\n",
|
||||
__func__, axis.x, axis.y, axis.z);
|
||||
|
||||
//memcpy(sense_data, &axis, sizeof(axis));
|
||||
mma8452_report_value(client, &axis);
|
||||
//atomic_set(&data_ready, 0);
|
||||
//wake_up(&data_ready_wq);
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
|
||||
mutex_lock(&(mma8452->sense_data_mutex) );
|
||||
mma8452->sense_data = axis;
|
||||
mutex_unlock(&(mma8452->sense_data_mutex) );
|
||||
|
||||
/* <20><>λ data_ready */
|
||||
atomic_set(&(mma8452->data_ready), 1);
|
||||
/* <20><><EFBFBD><EFBFBD> data_ready <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>ͷ. */
|
||||
wake_up(&(mma8452->data_ready_wq) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -366,6 +425,37 @@ static int mma8452_trans_buff(char *rbuf, int size)
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>Ѿ<EFBFBD> cache <20>˵<EFBFBD> sensor <20><><EFBFBD><EFBFBD>.
|
||||
* @param sense_data
|
||||
* ָ<><EFBFBD><F2B7B5BB><EFBFBD> buffer.
|
||||
* @param client
|
||||
* <20><>ǰ i2c client <20>豸ʵ<E8B1B8><CAB5><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8>.
|
||||
* @return
|
||||
* <20><><EFBFBD>ɹ<EFBFBD>, <20><><EFBFBD><EFBFBD> 0; <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
*/
|
||||
static int mma8452_get_cached_data(struct i2c_client* client, struct mma8452_axis* sense_data)
|
||||
{
|
||||
struct mma8452_data* this = (struct mma8452_data *)i2c_get_clientdata(client);
|
||||
|
||||
/* <20>г<EFBFBD>ʱ<EFBFBD><CAB1>, <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD> ready. */
|
||||
wait_event_interruptible_timeout(this->data_ready_wq,
|
||||
atomic_read(&(this->data_ready) ),
|
||||
msecs_to_jiffies(1000) );
|
||||
/* <20><><EFBFBD><EFBFBD>ʱ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB> ready. */
|
||||
if ( 0 == atomic_read(&(this->data_ready) ) ) {
|
||||
E("waiting 'data_ready_wq' timed out.");
|
||||
/* <20><><EFBFBD><EFBFBD> error. */
|
||||
return -1;
|
||||
}
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD> ready, <20><><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><D8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
|
||||
mutex_lock(&(this->sense_data_mutex) );
|
||||
*sense_data = this->sense_data;
|
||||
mutex_unlock(&(this->sense_data_mutex) );
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mma8452_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;//nonseekable_open(inode, file);
|
||||
@@ -381,13 +471,15 @@ static int mma8452_ioctl(struct inode *inode, struct file *file, unsigned int cm
|
||||
{
|
||||
|
||||
void __user *argp = (void __user *)arg;
|
||||
char msg[RBUFF_SIZE + 1];
|
||||
// char msg[RBUFF_SIZE + 1];
|
||||
struct mma8452_axis sense_data = {0};
|
||||
int ret = -1;
|
||||
char rate;
|
||||
struct i2c_client *client = container_of(mma8452_device.parent, struct i2c_client, dev);
|
||||
struct mma8452_data* this = (struct mma8452_data *)i2c_get_clientdata(client); /* <20>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>. */
|
||||
|
||||
switch (cmd) {
|
||||
case ECS_IOCTL_APP_SET_RATE:
|
||||
case MMA_IOCTL_APP_SET_RATE:
|
||||
if (copy_from_user(&rate, argp, sizeof(rate)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
@@ -396,36 +488,73 @@ static int mma8452_ioctl(struct inode *inode, struct file *file, unsigned int cm
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case ECS_IOCTL_START:
|
||||
ret = mma8452_start(client, MMA8452_RATE_12P5);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
case ECS_IOCTL_CLOSE:
|
||||
ret = mma8452_close(client);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
case ECS_IOCTL_APP_SET_RATE:
|
||||
case MMA_IOCTL_START:
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
mutex_lock(&(this->operation_mutex) );
|
||||
D("to perform 'MMA_IOCTL_START', former 'start_count' is %d.", this->start_count);
|
||||
/* <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>. */
|
||||
(this->start_count)++;
|
||||
/* <20><><EFBFBD>dz<EFBFBD><C7B3><EFBFBD> start, <20><>... */
|
||||
if ( 1 == this->start_count ) {
|
||||
/* <20><>λ data_ready. */
|
||||
atomic_set(&(this->data_ready), 0);
|
||||
/* ִ<>о<EFBFBD><D0BE><EFBFBD><EFBFBD>Ķ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
|
||||
if ( (ret = mma8452_start(client, MMA8452_RATE_12P5) ) < 0 ) {
|
||||
mutex_unlock(&(this->operation_mutex) );
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
mutex_unlock(&(this->operation_mutex) );
|
||||
D("finish 'MMA_IOCTL_START', ret = %d.", ret);
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
return 0;
|
||||
|
||||
case MMA_IOCTL_CLOSE:
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
mutex_lock(&(this->operation_mutex) );
|
||||
D("to perform 'MMA_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", this->start_count, get_current()->pid);
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD> 0, <20><>... */
|
||||
if ( 0 == (--(this->start_count) ) ) {
|
||||
/* <20><>λ data_ready. */
|
||||
atomic_set(&(this->data_ready), 0);
|
||||
/* ִ<>о<EFBFBD><D0BE><EFBFBD><EFBFBD>Ķ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD> stop <20><><EFBFBD><EFBFBD>. */
|
||||
if ( (ret = mma8452_close(client) ) < 0 ) {
|
||||
mutex_unlock(&(this->operation_mutex) );
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
mutex_unlock(&(this->operation_mutex) );
|
||||
/* <20><><EFBFBD><EFBFBD>. */
|
||||
return 0;
|
||||
|
||||
case MMA_IOCTL_APP_SET_RATE:
|
||||
ret = mma8452_reset_rate(client, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
/*
|
||||
case ECS_IOCTL_GETDATA:
|
||||
ret = mma8452_trans_buff(msg, RBUFF_SIZE);
|
||||
if (ret < 0)
|
||||
case MMA_IOCTL_GETDATA:
|
||||
// ret = mma8452_trans_buff(msg, RBUFF_SIZE);
|
||||
if ( (ret = mma8452_get_cached_data(client, &sense_data) ) < 0 ) {
|
||||
E("failed to get cached sense data, ret = %d.", ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case ECS_IOCTL_GETDATA:
|
||||
case MMA_IOCTL_GETDATA:
|
||||
/*
|
||||
if (copy_to_user(argp, &msg, sizeof(msg)))
|
||||
return -EFAULT;
|
||||
*/
|
||||
if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) {
|
||||
D("failed to copy sense data to user space.");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -452,8 +581,8 @@ static void mma8452_delaywork_func(struct work_struct *work)
|
||||
struct i2c_client *client = mma8452->client;
|
||||
|
||||
if (mma8452_get_data(client) < 0)
|
||||
mmaprintk(KERN_ERR "MMA8452 mma_work_func: Get data failed\n");
|
||||
mmaprintk("%s :int src:0x%02x\n",__FUNCTION__,mma845x_read_reg(mma8452->client,MMA8452_REG_INTSRC));
|
||||
E(KERN_ERR "MMA8452 mma_work_func: Get data failed\n");
|
||||
V("%s :int src:0x%02x\n",__FUNCTION__,mma845x_read_reg(mma8452->client,MMA8452_REG_INTSRC));
|
||||
enable_irq(client->irq);
|
||||
}
|
||||
|
||||
@@ -462,8 +591,9 @@ static irqreturn_t mma8452_interrupt(int irq, void *dev_id)
|
||||
struct mma8452_data *mma8452 = (struct mma8452_data *)dev_id;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
/* .! : <20>ӳٵ<D3B3><D9B5><EFBFBD> <20>װ벿 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>). */
|
||||
schedule_delayed_work(&mma8452->delaywork, msecs_to_jiffies(30));
|
||||
mmaprintk("%s :enter\n",__FUNCTION__);
|
||||
V("%s :enter\n",__FUNCTION__);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -474,6 +604,7 @@ static struct file_operations mma8452_fops = {
|
||||
.ioctl = mma8452_ioctl,
|
||||
};
|
||||
|
||||
/** <20><><EFBFBD><EFBFBD><EFBFBD>豸. */
|
||||
static struct miscdevice mma8452_device = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "mma8452_daemon",//"mma8452_daemon",
|
||||
@@ -548,12 +679,16 @@ static const struct i2c_device_id mma8452_id[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
/** <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>. */
|
||||
static struct i2c_driver mma8452_driver = {
|
||||
.driver = {
|
||||
.name = "gs_mma8452",
|
||||
},
|
||||
.id_table = mma8452_id,
|
||||
.probe = mma8452_probe,
|
||||
.probe = mma8452_probe, // .!! : <20><> probe() <20>ĵ<EFBFBD><C4B5><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ע<><D7A2><EFBFBD>豸<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>μ<EFBFBD> board-rk29sdk.c <20>е<EFBFBD> board_i2c0_devices.
|
||||
// <20><> board_i2c0_devices <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "gs_mma8452" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> I2C <20>豸.
|
||||
// ͬʱҲ<CAB1><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> I2C <20><>ַ <20><> <20>ն˺ŵ<CBBA><C5B5><EFBFBD>Ϣ.
|
||||
.remove = __devexit_p(mma8452_remove),
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
.suspend = &mma8452_suspend,
|
||||
@@ -687,8 +822,18 @@ static int mma8452_probe(struct i2c_client *client, const struct i2c_device_id
|
||||
register_early_suspend(&mma8452_early_suspend);
|
||||
#endif
|
||||
|
||||
mma8452->status = -1;
|
||||
printk(KERN_INFO "mma8452 probe ok\n");
|
||||
memset(&(mma8452->sense_data), 0, sizeof(struct mma8452_axis) );
|
||||
mutex_init(&(mma8452->sense_data_mutex) );
|
||||
|
||||
atomic_set(&(mma8452->data_ready), 0);
|
||||
init_waitqueue_head(&(mma8452->data_ready_wq) );
|
||||
|
||||
mma8452->start_count = 0;
|
||||
mutex_init(&(mma8452->operation_mutex) );
|
||||
|
||||
// mma8452->status = -1;
|
||||
mma8452->status = MMA8452_CLOSE;
|
||||
#if 0
|
||||
// mma8452_start_test(this_client);
|
||||
mma8452_start(client, MMA8452_RATE_12P5);
|
||||
@@ -711,7 +856,7 @@ exit_invalid_devid:
|
||||
exit_alloc_data_failed:
|
||||
;
|
||||
mmaprintk("%s error\n",__FUNCTION__);
|
||||
return err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "ak8975.h"
|
||||
|
||||
#define AKM8975_DEBUG 1
|
||||
#define AKM8975_DEBUG_MSG 1
|
||||
#define AKM8975_DEBUG_MSG 0
|
||||
#define AKM8975_DEBUG_FUNC 0
|
||||
#define AKM8975_DEBUG_DATA 0
|
||||
#define MAX_FAILURE_COUNT 3
|
||||
@@ -179,6 +179,8 @@ static int AKECS_SetMode_SngMeasure(void)
|
||||
{
|
||||
char buffer[2];
|
||||
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
atomic_set(&data_ready, 0);
|
||||
|
||||
/* Set measure mode */
|
||||
@@ -192,6 +194,7 @@ static int AKECS_SetMode_SngMeasure(void)
|
||||
static int AKECS_SetMode_SelfTest(void)
|
||||
{
|
||||
char buffer[2];
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
/* Set measure mode */
|
||||
buffer[0] = AK8975_REG_CNTL;
|
||||
@@ -203,6 +206,7 @@ static int AKECS_SetMode_SelfTest(void)
|
||||
static int AKECS_SetMode_FUSEAccess(void)
|
||||
{
|
||||
char buffer[2];
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
/* Set measure mode */
|
||||
buffer[0] = AK8975_REG_CNTL;
|
||||
@@ -214,6 +218,7 @@ static int AKECS_SetMode_FUSEAccess(void)
|
||||
static int AKECS_SetMode_PowerDown(void)
|
||||
{
|
||||
char buffer[2];
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
/* Set powerdown mode */
|
||||
buffer[0] = AK8975_REG_CNTL;
|
||||
@@ -225,6 +230,7 @@ static int AKECS_SetMode_PowerDown(void)
|
||||
static int AKECS_SetMode(char mode)
|
||||
{
|
||||
int ret;
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
switch (mode) {
|
||||
case AK8975_MODE_SNG_MEASURE:
|
||||
@@ -253,6 +259,7 @@ static int AKECS_CheckDevice(void)
|
||||
{
|
||||
char buffer[2];
|
||||
int ret;
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
/* Set measure mode */
|
||||
buffer[0] = AK8975_REG_WIA;
|
||||
@@ -279,6 +286,7 @@ static int AKECS_GetData(char *rbuf, int size)
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
wait_event_interruptible_timeout(data_ready_wq,
|
||||
atomic_read(&data_ready), 1000);
|
||||
if (!atomic_read(&data_ready)) {
|
||||
@@ -321,6 +329,7 @@ static void AKECS_SetYPR(short *rbuf)
|
||||
printk(KERN_INFO " Geomagnetism[LSB]: %6d,%6d,%6d\n",
|
||||
rbuf[9], rbuf[10], rbuf[11]);
|
||||
#endif
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
/* Report magnetic sensor information */
|
||||
if (atomic_read(&m_flag)) {
|
||||
input_report_abs(data->input_dev, ABS_RX, rbuf[0]);
|
||||
@@ -349,18 +358,21 @@ static void AKECS_SetYPR(short *rbuf)
|
||||
|
||||
static int AKECS_GetOpenStatus(void)
|
||||
{
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
wait_event_interruptible(open_wq, (atomic_read(&open_flag) != 0));
|
||||
return atomic_read(&open_flag);
|
||||
}
|
||||
|
||||
static int AKECS_GetCloseStatus(void)
|
||||
{
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
wait_event_interruptible(open_wq, (atomic_read(&open_flag) <= 0));
|
||||
return atomic_read(&open_flag);
|
||||
}
|
||||
|
||||
static void AKECS_CloseDone(void)
|
||||
{
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
atomic_set(&m_flag, 1);
|
||||
atomic_set(&a_flag, 1);
|
||||
atomic_set(&mv_flag, 1);
|
||||
@@ -398,6 +410,7 @@ akm_aot_ioctl(struct inode *inode, struct file *file,
|
||||
{
|
||||
void __user *argp = (void __user *)arg;
|
||||
short flag;
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
switch (cmd) {
|
||||
case ECS_IOCTL_APP_SET_MFLAG:
|
||||
@@ -487,6 +500,7 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
void __user *argp = (void __user *)arg;
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
/* NOTE: In this function the size of "char" should be 1-byte. */
|
||||
char sData[SENSOR_DATA_SIZE];/* for GETDATA */
|
||||
@@ -629,6 +643,7 @@ static void akm8975_work_func(struct work_struct *work)
|
||||
{
|
||||
char buffer[SENSOR_DATA_SIZE];
|
||||
int ret;
|
||||
AKMDBG("enter %s\n", __func__);
|
||||
|
||||
memset(buffer, 0, SENSOR_DATA_SIZE);
|
||||
buffer[0] = AK8975_REG_ST1;
|
||||
@@ -658,8 +673,9 @@ static irqreturn_t akm8975_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct akm8975_data *data = dev_id;
|
||||
AKMFUNC("akm8975_interrupt");
|
||||
disable_irq(this_client->irq);
|
||||
disable_irq_nosync(this_client->irq);
|
||||
schedule_work(&data->work);
|
||||
AKMDBG("exit %s\n", __func__);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -751,13 +767,22 @@ int akm8975_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
dev_dbg(&akm->client->dev, "no IRQ?\n");
|
||||
return -ENODEV;
|
||||
}else{
|
||||
AKMDBG("gpio %d to irq %d\n", akm->eoc_irq, gpio_to_irq(akm->eoc_irq));
|
||||
akm->eoc_irq = gpio_to_irq(akm->eoc_irq);
|
||||
}
|
||||
err = gpio_request(client->irq, "ak_8975");
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "failed to request GPIO, error %d\n", err);
|
||||
goto exit3;
|
||||
}
|
||||
}
|
||||
|
||||
err = gpio_direction_input(client->irq);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "failed to set GPIO direction, error %d\n", err);
|
||||
goto exit3;
|
||||
}
|
||||
gpio_pull_updown(client->irq, GPIOPullDown);
|
||||
|
||||
/* IRQ */
|
||||
err = request_irq(akm->eoc_irq, akm8975_interrupt, IRQ_TYPE_EDGE_RISING,
|
||||
"akm8975_DRDY", akm);
|
||||
@@ -766,6 +791,8 @@ int akm8975_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
goto exit4;
|
||||
}
|
||||
|
||||
client->irq = akm->eoc_irq;
|
||||
|
||||
/* Declare input device */
|
||||
akm->input_dev = input_allocate_device();
|
||||
if (!akm->input_dev) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
@@ -210,7 +211,10 @@ static void gt801_ts_work_func(struct work_struct *work)
|
||||
x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]);
|
||||
y = (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]);
|
||||
/* adjust the x and y to proper value added by hhb@rock-chips.com*/
|
||||
x = 480-x;
|
||||
if(x < 480){
|
||||
x = 480-x;
|
||||
}
|
||||
|
||||
if(y < 800){
|
||||
y = 800-y;
|
||||
}
|
||||
@@ -260,11 +264,12 @@ static enum hrtimer_restart gt801_ts_timer_func(struct hrtimer *timer)
|
||||
static irqreturn_t gt801_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gt801_ts_data *ts = dev_id;
|
||||
gt801printk("%s=%d,%d\n",__FUNCTION__,ts->client->irq,ts->use_irq);
|
||||
gt801printk("%s=%d,%d\n",__FUNCTION__,ts->client->irq,ts->use_irq);
|
||||
|
||||
//if (ts->use_irq)
|
||||
if(ts->use_irq){
|
||||
disable_irq_nosync(ts->client->irq);
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
}
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static int __devinit setup_resetPin(struct i2c_client *client, struct gt801_ts_data *ts)
|
||||
@@ -572,6 +577,17 @@ static int gt801_ts_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void gt801_ts_resume_work_func(struct work_struct *work)
|
||||
{
|
||||
struct gt801_ts_data *ts = container_of(work, struct gt801_ts_data, work);
|
||||
msleep(50); //touch panel will generate an interrupt when it sleeps out,so as to avoid tihs by delaying 50ms
|
||||
enable_irq(ts->client->irq);
|
||||
PREPARE_WORK(&ts->work, gt801_ts_work_func);
|
||||
printk("enabling gt801_ts IRQ %d\n", ts->client->irq);
|
||||
}
|
||||
|
||||
|
||||
static int gt801_ts_resume(struct i2c_client *client)
|
||||
{
|
||||
struct gt801_ts_data *ts = i2c_get_clientdata(client);
|
||||
@@ -581,13 +597,16 @@ static int gt801_ts_resume(struct i2c_client *client)
|
||||
printk("gt801 TS Resume\n");
|
||||
|
||||
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
|
||||
msleep(50);
|
||||
|
||||
if (ts->use_irq) {
|
||||
printk("enabling IRQ %d\n", client->irq);
|
||||
enable_irq(client->irq);
|
||||
if(!work_pending(&ts->work)){
|
||||
PREPARE_WORK(&ts->work, gt801_ts_resume_work_func);
|
||||
queue_work(gt801_wq, &ts->work);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -108,17 +108,19 @@ int rk29_gps_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rk29_gps_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if(!pdata)
|
||||
if(!pdata) {
|
||||
printk("%s: pdata = NULL ...... \n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pdata->power_flag == 1)
|
||||
{
|
||||
pdata->suspend = 1;
|
||||
queue_work(pdata->wq, &pdata->work);
|
||||
rk29_gps_uart_to_gpio(pdata->uart_id);
|
||||
pdata->power_down();
|
||||
pdata->reset(GPIO_LOW);
|
||||
}
|
||||
|
||||
printk("%s\n",__FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -126,48 +128,39 @@ int rk29_gps_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_gps_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if(!pdata)
|
||||
if(!pdata) {
|
||||
printk("%s: pdata = NULL ...... \n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pdata->power_flag == 1)
|
||||
{
|
||||
pdata->suspend = 0;
|
||||
queue_work(pdata->wq, &pdata->work);
|
||||
}
|
||||
|
||||
printk("%s\n",__FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk29_gps_delay_power_downup(struct work_struct *work)
|
||||
{
|
||||
//int ret;
|
||||
struct rk29_gps_data *pdata = container_of(work, struct rk29_gps_data, work);
|
||||
if (pdata == NULL) {
|
||||
printk("%s: pdata = NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("%s: suspend=%d\n", __func__, pdata->suspend);
|
||||
|
||||
down(&pdata->power_sem);
|
||||
//if (ret < 0) {
|
||||
// printk("%s: down power_sem error ret = %d\n", __func__, ret);
|
||||
// return ;
|
||||
//}
|
||||
|
||||
if (pdata->suspend) {
|
||||
rk29_gps_uart_to_gpio(pdata->uart_id);
|
||||
pdata->power_down();
|
||||
pdata->reset(GPIO_LOW);
|
||||
}
|
||||
else {
|
||||
pdata->reset(GPIO_LOW);
|
||||
mdelay(10);
|
||||
pdata->power_up();
|
||||
mdelay(500);
|
||||
pdata->reset(GPIO_HIGH);
|
||||
rk29_gps_gpio_to_uart(pdata->uart_id);
|
||||
}
|
||||
pdata->reset(GPIO_LOW);
|
||||
mdelay(5);
|
||||
pdata->power_up();
|
||||
msleep(500);
|
||||
pdata->reset(GPIO_HIGH);
|
||||
rk29_gps_gpio_to_uart(pdata->uart_id);
|
||||
|
||||
up(&pdata->power_sem);
|
||||
}
|
||||
|
||||
@@ -182,8 +175,11 @@ ssize_t rk29_gps_read(struct file *filp, char __user *ptr, size_t size, loff_t *
|
||||
{
|
||||
if (ptr == NULL)
|
||||
printk("%s: user space address is NULL\n", __func__);
|
||||
if (pgps == NULL)
|
||||
|
||||
if (pgps == NULL) {
|
||||
printk("%s: pgps addr is NULL\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
put_user(pgps->uart_id, ptr);
|
||||
|
||||
@@ -206,9 +202,9 @@ int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, uns
|
||||
switch (cmd){
|
||||
case ENABLE:
|
||||
pdata->reset(GPIO_LOW);
|
||||
mdelay(10);
|
||||
mdelay(5);
|
||||
pdata->power_up();
|
||||
mdelay(10);
|
||||
mdelay(5);
|
||||
rk29_gps_gpio_to_uart(pdata->uart_id);
|
||||
mdelay(500);
|
||||
pdata->reset(GPIO_HIGH);
|
||||
@@ -237,7 +233,7 @@ int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, uns
|
||||
|
||||
int rk29_gps_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
DBG("rk29_gps_release\n");
|
||||
DBG("rk29_gps_release\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -274,7 +270,6 @@ static int rk29_gps_probe(struct platform_device *pdev)
|
||||
pdata->wq = create_freezeable_workqueue("rk29_gps");
|
||||
INIT_WORK(&pdata->work, rk29_gps_delay_power_downup);
|
||||
pdata->power_flag = 0;
|
||||
pdata->suspend = 0;
|
||||
|
||||
pgps = pdata;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ struct rk29_gps_data {
|
||||
int (*reset)(int);
|
||||
int uart_id;
|
||||
int power_flag;
|
||||
int suspend;
|
||||
struct semaphore power_sem;
|
||||
struct workqueue_struct *wq;
|
||||
struct work_struct work;
|
||||
|
||||
27
include/linux/mma8452.h
Normal file → Executable file
27
include/linux/mma8452.h
Normal file → Executable file
@@ -54,17 +54,18 @@
|
||||
#define MMA8452_REG_OFF_Y 0x30 //RW
|
||||
#define MMA8452_REG_OFF_Z 0x31 //RW
|
||||
|
||||
#define MMAIO 0xA1
|
||||
//#define MMAIO 0xA1
|
||||
#define MMAIO 'm'
|
||||
|
||||
/* IOCTLs for MMA8452 library */
|
||||
#define ECS_IOCTL_INIT _IO(MMAIO, 0x01)
|
||||
#define ECS_IOCTL_RESET _IO(MMAIO, 0x04)
|
||||
#define ECS_IOCTL_CLOSE _IO(MMAIO, 0x02)
|
||||
#define ECS_IOCTL_START _IO(MMAIO, 0x03)
|
||||
#define ECS_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
|
||||
#define MMA_IOCTL_INIT _IO(MMAIO, 0x01)
|
||||
#define MMA_IOCTL_RESET _IO(MMAIO, 0x04)
|
||||
#define MMA_IOCTL_CLOSE _IO(MMAIO, 0x02)
|
||||
#define MMA_IOCTL_START _IO(MMAIO, 0x03)
|
||||
#define MMA_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
|
||||
|
||||
/* IOCTLs for APPs */
|
||||
#define ECS_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)
|
||||
#define MMA_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)
|
||||
|
||||
|
||||
/*rate*/
|
||||
@@ -89,8 +90,6 @@
|
||||
#define FREAD_MASK 2
|
||||
|
||||
|
||||
|
||||
|
||||
/*status*/
|
||||
#define MMA8452_SUSPEND 2
|
||||
#define MMA8452_OPEN 1
|
||||
@@ -115,15 +114,6 @@ struct mma8452_platform_data {
|
||||
|
||||
*/
|
||||
|
||||
struct mma8452_data {
|
||||
char status;
|
||||
char curr_tate;
|
||||
struct input_dev *input_dev;
|
||||
struct i2c_client *client;
|
||||
struct work_struct work;
|
||||
struct delayed_work delaywork; /*report second event*/
|
||||
};
|
||||
|
||||
struct mma8452_axis {
|
||||
int x;
|
||||
int y;
|
||||
@@ -132,6 +122,5 @@ struct mma8452_axis {
|
||||
|
||||
#define GSENSOR_DEV_PATH "/dev/mma8452_daemon"
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user