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
commit 995cebcf8a
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 log .
*
* -----------------------------------------------------------------------------------
* < > :
*
* -----------------------------------------------------------------------------------
*
* Usage: log .c , 使 log ,
* inclue , "#define ENABLE_DEBUG_LOG" .
* 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
// .! : 设备实例数据类型.
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*/
/** 缓存 sensor 数据. */
struct mma8452_axis sense_data;
/** 对 "sense_data" 的互斥保护. */
struct mutex sense_data_mutex;
/** 标识 "sense_data" 中的数据是否有效. */
atomic_t data_ready;
/** 用来等待 数据 ready 的等待队列头. */
wait_queue_head_t data_ready_wq;
/** 标识 设备被要求 START 采集数据的次数, 对应 MMA_IOCTL_START 可能被调用多次的情况. */
int start_count;
/** 对 'start_count' 和相关操作的互斥保护. */
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 定义在 mma8452.h 中.
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);
}
/** 在 底半部执行, 具体获取 g sensor 数据. */
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);
/* 互斥地缓存数据. */
mutex_lock(&(mma8452->sense_data_mutex) );
mma8452->sense_data = axis;
mutex_unlock(&(mma8452->sense_data_mutex) );
/* 置位 data_ready */
atomic_set(&(mma8452->data_ready), 1);
/* 唤醒 data_ready 等待队列头. */
wake_up(&(mma8452->data_ready_wq) );
return 0;
}
@ -366,6 +425,37 @@ static int mma8452_trans_buff(char *rbuf, int size)
}
*/
/**
* cache sensor .
* @param sense_data
* buffer.
* @param client
* i2c client .
* @return
* , 0; , .
*/
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);
/* 有超时地, 等待数据 ready. */
wait_event_interruptible_timeout(this->data_ready_wq,
atomic_read(&(this->data_ready) ),
msecs_to_jiffies(1000) );
/* 若超时, 且数据没有 ready. */
if ( 0 == atomic_read(&(this->data_ready) ) ) {
E("waiting 'data_ready_wq' timed out.");
/* 返回 error. */
return -1;
}
/* 数据已经 ready, 互斥地返回数据. */
mutex_lock(&(this->sense_data_mutex) );
*sense_data = this->sense_data;
mutex_unlock(&(this->sense_data_mutex) );
/* 返回. */
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); /* 设备数据实例的指针. */
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:
/* 上锁. */
mutex_lock(&(this->operation_mutex) );
D("to perform 'MMA_IOCTL_START', former 'start_count' is %d.", this->start_count);
/* 记数 自加. */
(this->start_count)++;
/* 若是初次 start, 则... */
if ( 1 == this->start_count ) {
/* 复位 data_ready. */
atomic_set(&(this->data_ready), 0);
/* 执行具体的对硬件的启动操作. */
if ( (ret = mma8452_start(client, MMA8452_RATE_12P5) ) < 0 ) {
mutex_unlock(&(this->operation_mutex) );
return ret;
}
}
/* 解锁. */
mutex_unlock(&(this->operation_mutex) );
D("finish 'MMA_IOCTL_START', ret = %d.", ret);
/* 返回. */
return 0;
case MMA_IOCTL_CLOSE:
/* 上锁. */
mutex_lock(&(this->operation_mutex) );
D("to perform 'MMA_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", this->start_count, get_current()->pid);
/* 若记数自减到 0, 则... */
if ( 0 == (--(this->start_count) ) ) {
/* 复位 data_ready. */
atomic_set(&(this->data_ready), 0);
/* 执行具体的对硬件的 stop 操作. */
if ( (ret = mma8452_close(client) ) < 0 ) {
mutex_unlock(&(this->operation_mutex) );
return ret;
}
}
/* 解锁. */
mutex_unlock(&(this->operation_mutex) );
/* 返回. */
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);
/* .! : 延迟地在 底半部 发起后续操作(读取具体数据). */
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,
};
/** 控制设备. */
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[] = {
{ }
};
/** 表征驱动的数据类型定义. */
static struct i2c_driver mma8452_driver = {
.driver = {
.name = "gs_mma8452",
},
.id_table = mma8452_id,
.probe = mma8452_probe,
.probe = mma8452_probe, // .!! : 对 probe() 的调用, 仍是由 注册设备的操作触发的,
// 具体参见 board-rk29sdk.c 中的 board_i2c0_devices.
// 在 board_i2c0_devices 中声明了一个可以使用名称是 "gs_mma8452" 驱动程序的 I2C 设备.
// 同时也体现了 I2C 地址 和 终端号等信息.
.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 @@ static int mma8452_probe(struct i2c_client *client, const struct i2c_device_id
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