diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index 75d7669e..19e42d60 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -197,6 +197,7 @@ static struct akm8973_platform_data compass_platform_data = static struct bma150_platform_data htcleo_g_sensor_pdata = { .microp_new_cmd = 0, + .chip_layout = 1, }; static struct platform_device microp_devices[] = { diff --git a/drivers/misc/bma150_spi.c b/drivers/misc/bma150_spi.c index 0dd16bef..41541114 100644 --- a/drivers/misc/bma150_spi.c +++ b/drivers/misc/bma150_spi.c @@ -32,6 +32,9 @@ static struct bma150_platform_data *this_pdata; static struct mutex gsensor_RW_mutex; static struct mutex gsensor_set_mode_mutex; +static atomic_t PhoneOn_flag = ATOMIC_INIT(0); +#define DEVICE_ACCESSORY_ATTR(_name, _mode, _show, _store) \ +struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) static int spi_microp_enable(uint8_t on) { int ret; @@ -219,7 +222,7 @@ static int spi_bma150_TransRBuff(short *rbuf) static int __spi_bma150_set_mode(char mode) { - char buffer[2]; + char buffer[2] = ""; int ret; mutex_lock(&gsensor_set_mode_mutex); if (mode == BMA_MODE_NORMAL) { @@ -263,15 +266,17 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int unsigned long arg) { void __user *argp = (void __user *)arg; - char rwbuf[8]; + char rwbuf[8] = ""; char *toRbuf; int ret = -1; short buf[8], temp; + int kbuf = 0; switch (cmd) { case BMA_IOCTL_READ: case BMA_IOCTL_WRITE: case BMA_IOCTL_SET_MODE: + case BMA_IOCTL_SET_CALI_MODE: if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) return -EFAULT; break; @@ -279,6 +284,10 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int if (copy_from_user(&buf, argp, sizeof(buf))) return -EFAULT; break; + case BMA_IOCTL_WRITE_CALI_VALUE: + if (copy_from_user(&kbuf, argp, sizeof(kbuf))) + return -EFAULT; + break; default: break; } @@ -304,11 +313,25 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int if (ret < 0) return ret; break; + case BMA_IOCTL_WRITE_CALI_VALUE: + this_pdata->gs_kvalue = kbuf; + break; case BMA_IOCTL_READ_ACCELERATION: ret = spi_bma150_TransRBuff(&buf[0]); if (ret < 0) return ret; break; + case BMA_IOCTL_READ_CALI_VALUE: + if ((this_pdata->gs_kvalue & (0x67 << 24)) != (0x67 << 24)) { + rwbuf[0] = 0; + rwbuf[1] = 0; + rwbuf[2] = 0; + } else { + rwbuf[0] = (this_pdata->gs_kvalue >> 16) & 0xFF; + rwbuf[1] = (this_pdata->gs_kvalue >> 8) & 0xFF; + rwbuf[2] = this_pdata->gs_kvalue & 0xFF; + } + break; case BMA_IOCTL_SET_MODE: /*printk(KERN_DEBUG "%s: BMA_IOCTL_SET_MODE by ioctl = %d\n", @@ -324,6 +347,14 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int if (this_pdata) temp = this_pdata->chip_layout; break; + case BMA_IOCTL_GET_CALI_MODE: + if (this_pdata) + temp = this_pdata->calibration_mode; + break; + case BMA_IOCTL_SET_CALI_MODE: + if (this_pdata) + this_pdata->calibration_mode = rwbuf[0]; + break; default: return -ENOTTY; } @@ -338,6 +369,10 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int if (copy_to_user(argp, &buf, sizeof(buf))) return -EFAULT; break; + case BMA_IOCTL_READ_CALI_VALUE: + if (copy_to_user(argp, &rwbuf, sizeof(rwbuf))) + return -EFAULT; + break; case BMA_IOCTL_GET_INT: if (copy_to_user(argp, &temp, sizeof(temp))) return -EFAULT; @@ -346,6 +381,10 @@ static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int if (copy_to_user(argp, &temp, sizeof(temp))) return -EFAULT; break; + case BMA_IOCTL_GET_CALI_MODE: + if (copy_to_user(argp, &temp, sizeof(temp))) + return -EFAULT; + break; default: break; } @@ -369,7 +408,10 @@ static struct miscdevice spi_bma_device = { static void bma150_early_suspend(struct early_suspend *handler) { int ret = 0; + if (!atomic_read(&PhoneOn_flag)) { ret = __spi_bma150_set_mode(BMA_MODE_SLEEP); + } else + printk(KERN_DEBUG "bma150_early_suspend: PhoneOn_flag is set\n"); /*printk(KERN_DEBUG "%s: spi_bma150_set_mode returned = %d!\n", @@ -382,6 +424,74 @@ static void bma150_early_resume(struct early_suspend *handler) "%s: spi_bma150_set_mode returned = %d!\n", __func__, ret);*/ } +static ssize_t spi_bma150_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char *s = buf; + s += sprintf(s, "%d\n", atomic_read(&PhoneOn_flag)); + return (s - buf); +} + +static ssize_t spi_bma150_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (count == (strlen("enable") + 1) && + strncmp(buf, "enable", strlen("enable")) == 0) { + atomic_set(&PhoneOn_flag, 1); + printk(KERN_DEBUG "spi_bma150_store: PhoneOn_flag=%d\n", atomic_read(&PhoneOn_flag)); + return count; + } + if (count == (strlen("disable") + 1) && + strncmp(buf, "disable", strlen("disable")) == 0) { + atomic_set(&PhoneOn_flag, 0); + printk(KERN_DEBUG "spi_bma150_store: PhoneOn_flag=%d\n", atomic_read(&PhoneOn_flag)); + return count; + } + printk(KERN_ERR "spi_bma150_store: invalid argument\n"); + return -EINVAL; + +} + +static DEVICE_ACCESSORY_ATTR(PhoneOnOffFlag, 0666, \ + spi_bma150_show, spi_bma150_store); + +int spi_bma150_registerAttr(void) +{ + int ret; + struct class *htc_accelerometer_class; + struct device *accelerometer_dev; + + htc_accelerometer_class = class_create(THIS_MODULE, "htc_accelerometer"); + if (IS_ERR(htc_accelerometer_class)) { + ret = PTR_ERR(htc_accelerometer_class); + htc_accelerometer_class = NULL; + goto err_create_class; + } + + accelerometer_dev = device_create(htc_accelerometer_class, + NULL, 0, "%s", "accelerometer"); + if (unlikely(IS_ERR(accelerometer_dev))) { + ret = PTR_ERR(accelerometer_dev); + accelerometer_dev = NULL; + goto err_create_accelerometer_device; + } + + /* register the attributes */ + ret = device_create_file(accelerometer_dev, &dev_attr_PhoneOnOffFlag); + if (ret) + goto err_create_accelerometer_device_file; + + return 0; + +err_create_accelerometer_device_file: + device_unregister(accelerometer_dev); +err_create_accelerometer_device: + class_destroy(htc_accelerometer_class); +err_create_class: + + return ret; +} static int spi_gsensor_initial(void) { @@ -429,8 +539,14 @@ static int spi_gsensor_initial(void) bma_early_suspend.resume = bma150_early_resume; register_early_suspend(&bma_early_suspend); + ret = spi_bma150_registerAttr(); + if (ret) { + printk(KERN_ERR "%s: set spi_bma150_registerAttr fail!\n", __func__); + goto err_registerAttr; + } return 0; +err_registerAttr: err_set_mode: spi_microp_enable(0); err_spi_enable: @@ -441,10 +557,15 @@ err_spi_enable: static int spi_bma150_probe(struct platform_device *pdev) { + + unsigned int gs_kvalue=0; printk(KERN_INFO "%s: G-sensor connect with microP: " - "start initial\n", __func__); + "start initial, kvalue = 0x%x\n", __func__, gs_kvalue); this_pdata = pdev->dev.platform_data; + + this_pdata->gs_kvalue = gs_kvalue; + /* printk(KERN_DEBUG "%s: this_pdata->microp_new_cmd = %d\n", __func__, this_pdata->microp_new_cmd); diff --git a/include/linux/bma150.h b/include/linux/bma150.h index d1bf5dc2..2b91f1e4 100644 --- a/include/linux/bma150.h +++ b/include/linux/bma150.h @@ -7,11 +7,7 @@ #include #define BMA150_I2C_NAME "bma150" -#ifdef CONFIG_MACH_HTCLEO -#define BMA150_G_SENSOR_NAME "bma150" // To be compatible with other userspace -#else #define BMA150_G_SENSOR_NAME "bma150_uP_spi" -#endif #define BMAIO 0xA1 @@ -57,6 +53,10 @@ #define BMA_IOCTL_SET_MODE _IOW(BMAIO, 0x35, short) #define BMA_IOCTL_GET_INT _IOR(BMAIO, 0x36, short) #define BMA_IOCTL_GET_CHIP_LAYOUT _IOR(BMAIO, 0x37, short) +#define BMA_IOCTL_GET_CALI_MODE _IOR(BMAIO, 0x38, short) +#define BMA_IOCTL_SET_CALI_MODE _IOW(BMAIO, 0x39, short) +#define BMA_IOCTL_READ_CALI_VALUE _IOR(BMAIO, 0x3a, char[3]) +#define BMA_IOCTL_WRITE_CALI_VALUE _IOW(BMAIO, 0x3b, int) /* range and bandwidth */ #define BMA_RANGE_2G 0 @@ -75,10 +75,14 @@ #define BMA_MODE_NORMAL 0 #define BMA_MODE_SLEEP 1 +extern unsigned int gs_kvalue; + struct bma150_platform_data { int intr; int microp_new_cmd; int chip_layout; + int calibration_mode; + int gs_kvalue; }; #endif