mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 07:32:29 +02:00
Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
This commit is contained in:
commit
995cebcf8a
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 偏好的 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__ */
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
// .! : 设备实例数据类型.
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user