Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop

This commit is contained in:
蔡枫
2011-04-21 13:36:00 +08:00
8 changed files with 355 additions and 96 deletions

View 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__ */

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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
View 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