htcleo: fixed proximity and lightsensor power

This commit is contained in:
Markinus 2011-01-29 12:05:43 +01:00 committed by tytung
parent 1130964c5c
commit ed4a7e4037
4 changed files with 45 additions and 40 deletions

View File

@ -39,6 +39,7 @@ user may be able to adjust time in future
#include <mach/board-htcleo-microp.h>
#include "board-htcleo.h"
struct early_suspend early_suspend;
//#define CFG_LSENSOR_TYPE
@ -47,7 +48,7 @@ user may be able to adjust time in future
//#define LSENSOR_ABLK_ONLY 2
#define LSENSOR_POLL_PROMESHUTOK 5000
#define LSENSOR_POLL_PROMESHUTOK 1000
#define D(x...) pr_debug(x)
// pr_info(x)
@ -274,6 +275,18 @@ struct miscdevice lightsensor_misc =
.fops = &lightsensor_fops
};
#ifdef CONFIG_HAS_EARLYSUSPEND
static void lightsensor_suspend(struct early_suspend *h)
{
lightsensor_disable();
}
static void lightsensor_resume(struct early_suspend *h)
{
lightsensor_enable();
}
#endif
//////////////////////////////////////////////////////////////////////////
static int lsensor_probe(struct platform_device *pdev)
@ -328,6 +341,15 @@ static int lsensor_probe(struct platform_device *pdev)
the_data.enabled=0;
the_data.opened=0;
INIT_DELAYED_WORK(&the_data.work, lightsensor_poll_function);
lightsensor_enable();
#ifdef CONFIG_HAS_EARLYSUSPEND
early_suspend.level =
EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
early_suspend.suspend = lightsensor_suspend;
early_suspend.resume = lightsensor_resume;
register_early_suspend(&early_suspend);
#endif
if (!ret)
goto done;

View File

@ -34,7 +34,6 @@
#include <linux/jiffies.h>
#include <linux/wakelock.h>
#include <linux/earlysuspend.h>
#include <linux/capella_cm3602.h>
#include <linux/bma150.h>
#include <asm/uaccess.h>
#include <asm/mach-types.h>
@ -331,7 +330,7 @@ int microp_read_gpo_status(uint16_t *status)
}
EXPORT_SYMBOL(microp_read_gpo_status);
int microp_gpo_enable(uint16_t interrupt_mask)
int microp_gpo_enable(uint16_t gpo_mask)
{
uint8_t data[2];
int ret = -1;
@ -339,17 +338,17 @@ int microp_gpo_enable(uint16_t interrupt_mask)
client = private_microp_client;
data[0] = interrupt_mask >> 8;
data[1] = interrupt_mask & 0xFF;
data[0] = gpo_mask >> 8;
data[1] = gpo_mask & 0xFF;
ret = i2c_write_block(client, MICROP_I2C_WCMD_GPO_LED_STATUS_EN, data, 2);
if (ret < 0)
dev_err(&client->dev, "%s: enable 0x%x interrupt failed\n", __func__, interrupt_mask);
dev_err(&client->dev, "%s: enable 0x%x interrupt failed\n", __func__, gpo_mask);
return ret;
}
EXPORT_SYMBOL(microp_gpo_enable);
int microp_gpo_disable(uint16_t interrupt_mask)
int microp_gpo_disable(uint16_t gpo_mask)
{
uint8_t data[2];
int ret = -1;
@ -357,36 +356,16 @@ int microp_gpo_disable(uint16_t interrupt_mask)
client = private_microp_client;
data[0] = interrupt_mask >> 8;
data[1] = interrupt_mask & 0xFF;
data[0] = gpo_mask >> 8;
data[1] = gpo_mask & 0xFF;
ret = i2c_write_block(client, MICROP_I2C_WCMD_GPO_LED_STATUS_DIS, data, 2);
if (ret < 0)
dev_err(&client->dev, "%s: disable 0x%x interrupt failed\n", __func__, interrupt_mask);
dev_err(&client->dev, "%s: disable 0x%x interrupt failed\n", __func__, gpo_mask);
return ret;
}
EXPORT_SYMBOL(microp_gpo_disable);
/*
* CM3602 Power for LS and Proximity
*/
int __capella_cm3602_power(int on)
{
int rc;
pr_debug("%s: Turn the capella_cm3602 power %s\n",
__func__, (on) ? "on" : "off");
if (on) {
rc = microp_gpo_enable(GPO_CM3602);
if (rc < 0)
return -EIO;
} else {
rc = microp_gpo_disable(GPO_CM3602);
if (rc < 0)
return -EIO;
}
return 0;
}
int capella_cm3602_power(int pwr_device, uint8_t enable)
{
@ -396,6 +375,7 @@ int capella_cm3602_power(int pwr_device, uint8_t enable)
mutex_lock(&capella_cm3602_lock);
if(pwr_device==PS_PWR_ON) { // Switch the Proximity IRQ
if(enable) {
microp_gpo_enable(PS_PWR_ON);
ret = microp_interrupt_get_status(&interrupts);
if (ret < 0) {
pr_err("%s: read interrupt status fail\n", __func__);
@ -407,13 +387,13 @@ int capella_cm3602_power(int pwr_device, uint8_t enable)
else {
interrupts |= IRQ_PROXIMITY;
ret = microp_interrupt_disable(interrupts);
microp_gpo_disable(PS_PWR_ON);
}
if (ret < 0) {
pr_err("%s: failed to enable gpi irqs\n", __func__);
return ret;
}
}
old_status = als_power_control;
if (enable)
als_power_control |= pwr_device;
@ -422,10 +402,9 @@ int capella_cm3602_power(int pwr_device, uint8_t enable)
on = als_power_control ? 1 : 0;
if (old_status == 0 && on)
ret = __capella_cm3602_power(1);
microp_gpo_enable(LS_PWR_ON);
else if (!on)
ret = __capella_cm3602_power(0);
microp_gpo_disable(LS_PWR_ON);
mutex_unlock(&capella_cm3602_lock);
return ret;
}
@ -472,7 +451,6 @@ static void microp_i2c_intr_work_func(struct work_struct *work)
dev_err(&client->dev, "%s: clear interrupt status fail\n",
__func__);
}
pr_info("intr_status=0x%02x\n", intr_status);
if (intr_status & IRQ_PROXIMITY) {
p_sensor_irq_handler();

View File

@ -19,7 +19,6 @@
#include <linux/earlysuspend.h>
#include <asm/mach-types.h>
#include <mach/board-htcleo-microp.h>
#include <linux/capella_cm3602.h>
#include <linux/input.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
@ -30,7 +29,6 @@
#include "board-htcleo.h"
#define INT_PSENSOR (1<<4)
#define GPO_PROXIMITY 0x3
#define D(x...) pr_debug(x)

View File

@ -47,6 +47,8 @@ struct microp_i2c_client_data {
uint8_t enable_reset_button;
int microp_is_suspend;
uint32_t microp_als_kadc;
struct hrtimer gen_irq_timer;
uint16_t intr_status;
};
#define MICROP_I2C_NAME "htcleo-microp"
@ -122,9 +124,14 @@ struct microp_i2c_client_data {
#define READ_GPI_STATE_HPIN (1<<2)
#define READ_GPI_STATE_SDCARD (1<<0)
#define GPO_CM3602 0x3
#define LS_PWR_ON (1 << 0)
#define PS_PWR_ON (1 << 1)
#define PS_PWR_ON (1 << 0)
#define LS_PWR_ON (1 << 1)
#define CAPELLA_CM3602_IOCTL_MAGIC 'c'
#define CAPELLA_CM3602_IOCTL_GET_ENABLED \
_IOR(CAPELLA_CM3602_IOCTL_MAGIC, 1, int *)
#define CAPELLA_CM3602_IOCTL_ENABLE \
_IOW(CAPELLA_CM3602_IOCTL_MAGIC, 2, int *)
int microp_i2c_read(uint8_t addr, uint8_t *data, int length);
int microp_i2c_write(uint8_t addr, uint8_t *data, int length);