mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-01 02:21:16 +00:00
input: sensor: add cm36283 devicetree support
Add Capella cm36283 ambient light/proximity sensor devicetree support to make it compatible with the current Linux kernel structure. Change-Id: I23d7916480d1924b4a0a8121b2a587993a1d4b61 Signed-off-by: Oliver Wang <mengmeng@codeaurora.org>
This commit is contained in:
parent
574a33be22
commit
e63fc3c340
4 changed files with 152 additions and 7 deletions
40
Documentation/devicetree/bindings/input/misc/cm36283.txt
Normal file
40
Documentation/devicetree/bindings/input/misc/cm36283.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
Capella cm36283 L/P sensor
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Should be "capella,cm36283".
|
||||
- reg : i2c slave address of the device.
|
||||
- interrupt-parent : Parent of interrupt.
|
||||
- interrupts : L/P sample interrupt to indicate new data ready.
|
||||
- vdd-supply : Power supply needed to power up the device.
|
||||
- vio-supply : IO power supply needed for IO and I2C.
|
||||
- capella,interrupt-gpio : The gpio pin for the interrupt.
|
||||
- capella,levels : The adc value for light sensor to trigger different light level.
|
||||
- capella,ps_close_thd_set : The threshold adc value for proximity sensor to trigger close interrupt.
|
||||
- capella,ps_away_thd_set: The threshold adc value for proximity sensor to trigger away interrupt.
|
||||
- capella,ls_cmd : The initial value to configure cm36283 ALS_CONF register.
|
||||
- capella,ps_conf1_val : The initial value to configure cm36283 PS_CONF1 register.
|
||||
- capella,ps_conf3_val : The initial value to configure cm36283 PS_CONF3 register.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- capella,use-polling : Property to specify if using polling instead of interrupt for adc value report.
|
||||
|
||||
Example:
|
||||
|
||||
capella@60 {
|
||||
compatible = "capella,cm36283";
|
||||
reg = <0x60>;
|
||||
interrupt-parent = <&msmgpio>;
|
||||
interrupts = <80 0x2>;
|
||||
vdd-supply = <&pm8110_l19>;
|
||||
vio-supply = <&pm8110_l14>;
|
||||
capella,use-polling;
|
||||
capella,interrupt-gpio = <80>;
|
||||
capella,levels = <0x0A 0xA0 0xE1 0x140 0x280 0x500 0xA28 0x16A8 0x1F40 0x2800>;
|
||||
capella,ps_close_thd_set = <0xa>;
|
||||
capella,ps_away_thd_set = <0x5>;
|
||||
capella,ls_cmd = <0x44>; /* PS_IT=160ms, INT_PERS=2*/
|
||||
capella,ps_conf1_val = <0x0006>; /*CM36283_PS_ITB_1_2 | CM36283_PS_DR_1_40| CM36283_PS_IT_1T | CM36283_PS_PERS_2 | CM36283_PS_RES_1*/
|
||||
capella,ps_conf3_val = <0x3010>; /* CM36283_PS_MS_NORMAL | CM36283_PS_PROL_255 | CM36283_PS_SMART_PERS_ENABLE, */
|
||||
};
|
|
@ -13,6 +13,7 @@ arm ARM Ltd.
|
|||
atmel Atmel Corporation
|
||||
bosch Bosch Sensortec GmbH
|
||||
brcm Broadcom Corporation
|
||||
capella Capella Microsystems, Inc.
|
||||
cavium Cavium, Inc.
|
||||
chrp Common Hardware Reference Platform
|
||||
cirrus Cirrus Logic, Inc.
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
*
|
||||
* Copyright (C) 2012 Capella Microsystems Inc.
|
||||
* Author: Frank Hsieh <pengyueh@gmail.com>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
|
@ -32,6 +34,7 @@
|
|||
#include <linux/wakelock.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/cm36283.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -1274,6 +1277,78 @@ static void cm36283_late_resume(struct early_suspend *h)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int cm36283_parse_dt(struct device *dev,
|
||||
struct cm36283_platform_data *pdata)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
u32 levels[CM36283_LEVELS_SIZE], i;
|
||||
u32 temp_val;
|
||||
int rc;
|
||||
|
||||
rc = of_get_named_gpio_flags(np, "capella,interrupt-gpio",
|
||||
0, NULL);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "Unable to read interrupt pin number\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->intr = rc;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(np, "capella,levels", levels,
|
||||
CM36283_LEVELS_SIZE);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read levels data\n");
|
||||
return rc;
|
||||
} else {
|
||||
for (i = 0; i < CM36283_LEVELS_SIZE; i++)
|
||||
pdata->levels[i] = levels[i];
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "capella,ps_close_thd_set", &temp_val);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read ps_close_thd_set\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->ps_close_thd_set = (u8)temp_val;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "capella,ps_away_thd_set", &temp_val);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read ps_away_thd_set\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->ps_away_thd_set = (u8)temp_val;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "capella,ls_cmd", &temp_val);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read ls_cmd\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->ls_cmd = (u16)temp_val;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "capella,ps_conf1_val", &temp_val);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read ps_conf1_val\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->ps_conf1_val = (u16)temp_val;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "capella,ps_conf3_val", &temp_val);
|
||||
if (rc) {
|
||||
dev_err(dev, "Unable to read ps_conf3_val\n");
|
||||
return rc;
|
||||
} else {
|
||||
pdata->ps_conf3_val = (u16)temp_val;
|
||||
}
|
||||
|
||||
pdata->polling = of_property_read_bool(np, "capella,use-polling");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cm36283_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -1291,12 +1366,29 @@ static int cm36283_probe(struct i2c_client *client,
|
|||
/*D("[CM36283] %s: client->irq = %d\n", __func__, client->irq);*/
|
||||
|
||||
lpi->i2c_client = client;
|
||||
pdata = client->dev.platform_data;
|
||||
if (!pdata) {
|
||||
pr_err("[PS][CM36283 error]%s: Assign platform_data error!!\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto err_platform_data_null;
|
||||
|
||||
if (client->dev.of_node) {
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
dev_err(&client->dev, "Failed to allocate memory for pdata\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_platform_data_null;
|
||||
}
|
||||
|
||||
ret = cm36283_parse_dt(&client->dev, pdata);
|
||||
pdata->slave_addr = client->addr;
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "Failed to get pdata from device tree\n");
|
||||
goto err_parse_dt;
|
||||
}
|
||||
} else {
|
||||
pdata = client->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&client->dev, "%s: Assign platform_data error!!\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto err_platform_data_null;
|
||||
}
|
||||
}
|
||||
|
||||
lpi->irq = client->irq;
|
||||
|
@ -1502,6 +1594,9 @@ err_lightsensor_setup:
|
|||
mutex_destroy(&als_enable_mutex);
|
||||
mutex_destroy(&als_disable_mutex);
|
||||
mutex_destroy(&als_get_adc_mutex);
|
||||
err_parse_dt:
|
||||
if (client->dev.of_node && (pdata != NULL))
|
||||
devm_kfree(&client->dev, pdata);
|
||||
err_platform_data_null:
|
||||
kfree(lpi);
|
||||
return ret;
|
||||
|
@ -1769,6 +1864,11 @@ static const struct i2c_device_id cm36283_i2c_id[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static struct of_device_id cm36283_match_table[] = {
|
||||
{ .compatible = "capella,cm36283",},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver cm36283_driver = {
|
||||
.id_table = cm36283_i2c_id,
|
||||
.probe = cm36283_probe,
|
||||
|
@ -1776,6 +1876,7 @@ static struct i2c_driver cm36283_driver = {
|
|||
.name = CM36283_I2C_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &cm36283_pm,
|
||||
.of_match_table = cm36283_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@
|
|||
extern unsigned int ps_kparam1;
|
||||
extern unsigned int ps_kparam2;
|
||||
|
||||
#define CM36283_LEVELS_SIZE 10
|
||||
|
||||
struct cm36283_platform_data {
|
||||
int intr;
|
||||
uint16_t levels[10];
|
||||
|
@ -131,6 +133,7 @@ struct cm36283_platform_data {
|
|||
uint16_t ls_cmd;
|
||||
uint16_t ps_conf1_val;
|
||||
uint16_t ps_conf3_val;
|
||||
bool polling;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue