diff options
-rw-r--r-- | Documentation/devicetree/bindings/input/capella-cm3217.txt | 16 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/vendor-prefixes.txt | 1 | ||||
-rw-r--r-- | arch/arm/configs/tegra11_android_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/configs/tegra11_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/configs/tegra3_android_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/configs/tegra3_android_dgpu_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/configs/tegra_dalmore_mods_defconfig | 2 | ||||
-rw-r--r-- | drivers/input/misc/Kconfig | 6 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/iio/light/Kconfig | 7 | ||||
-rw-r--r-- | drivers/staging/iio/light/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/iio/light/cm3217.c (renamed from drivers/input/misc/cm3217.c) | 157 | ||||
-rw-r--r-- | include/linux/cm3217.h | 7 |
13 files changed, 152 insertions, 54 deletions
diff --git a/Documentation/devicetree/bindings/input/capella-cm3217.txt b/Documentation/devicetree/bindings/input/capella-cm3217.txt new file mode 100644 index 000000000000..d67f9ba820d2 --- /dev/null +++ b/Documentation/devicetree/bindings/input/capella-cm3217.txt @@ -0,0 +1,16 @@ +* Capella CM3217 light sensor + +Required properties: +- compatible: "capella,cm3217" +- reg : the I2C address of CM3217 +- levels : threshold ADC value array for each illuminance levels +- golden_adc : golden ADC value. if adc raw value on step = 0.3 lux, set this to 3. + +Example: + +cm3217@10 { + compatible = "capella,cm3217"; + reg = <0x10>; + levels = <10 160 225 320 640 1280 2600 5800 8000 10240>; + golden_adc = <3>; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 82ac057a24a9..d7564379c98a 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -8,6 +8,7 @@ amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. atmel Atmel Corporation +capella Capella Microsystems, Inc. cavium Cavium, Inc. chrp Common Hardware Reference Platform cortina Cortina Systems, Inc. diff --git a/arch/arm/configs/tegra11_android_defconfig b/arch/arm/configs/tegra11_android_defconfig index 09052ec77a16..c000131e3b98 100644 --- a/arch/arm/configs/tegra11_android_defconfig +++ b/arch/arm/configs/tegra11_android_defconfig @@ -274,7 +274,6 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_MAX77665_HAPTIC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y -CONFIG_INPUT_CAPELLA_CM3217=y CONFIG_INPUT_CAPELLA_CM3218=y CONFIG_INV_AK8975=m CONFIG_INV_MPU=m @@ -317,6 +316,7 @@ CONFIG_CHARGER_GPIO=y CONFIG_SENSORS_INA219=y CONFIG_SENSORS_INA230=y CONFIG_SENSORS_INA3221=y +CONFIG_SENSORS_CM3217=y CONFIG_THERMAL=y CONFIG_THERMAL_GOV_PID=y CONFIG_PWM_FAN=y diff --git a/arch/arm/configs/tegra11_defconfig b/arch/arm/configs/tegra11_defconfig index 4dc91afb4af2..87648e5a2d3f 100644 --- a/arch/arm/configs/tegra11_defconfig +++ b/arch/arm/configs/tegra11_defconfig @@ -264,7 +264,6 @@ CONFIG_TOUCHSCREEN_SYN_RMI4_SPI=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y -CONFIG_INPUT_CAPELLA_CM3217=y CONFIG_INV_AK8975=m CONFIG_INV_MPU=m CONFIG_SERIO_LIBPS2=y @@ -299,6 +298,7 @@ CONFIG_CHARGER_SMB349=y CONFIG_BATTERY_MAX17048=y CONFIG_CHARGER_GPIO=y CONFIG_SENSORS_INA219=y +CONFIG_SENSORS_CM3217=y CONFIG_THERMAL=y CONFIG_MFD_TPS6586X=y CONFIG_MFD_TPS65910=y diff --git a/arch/arm/configs/tegra3_android_defconfig b/arch/arm/configs/tegra3_android_defconfig index 70240b59ee89..fae72542319c 100644 --- a/arch/arm/configs/tegra3_android_defconfig +++ b/arch/arm/configs/tegra3_android_defconfig @@ -260,7 +260,6 @@ CONFIG_TOUCHSCREEN_SYN_RMI4_SPI=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y -CONFIG_INPUT_CAPELLA_CM3217=y CONFIG_INV_BMP180=m CONFIG_INV_AK8975=m CONFIG_INV_MPU=m @@ -297,6 +296,7 @@ CONFIG_BATTERY_MAX17048=y CONFIG_CHARGER_GPIO=y CONFIG_SENSORS_TEGRA_TSENSOR=y CONFIG_SENSORS_INA219=y +CONFIG_SENSORS_CM3217=y CONFIG_THERMAL=y CONFIG_MFD_TPS6586X=y CONFIG_MFD_TPS65910=y diff --git a/arch/arm/configs/tegra3_android_dgpu_defconfig b/arch/arm/configs/tegra3_android_dgpu_defconfig index b0197b52a43f..1c583a5c7140 100644 --- a/arch/arm/configs/tegra3_android_dgpu_defconfig +++ b/arch/arm/configs/tegra3_android_dgpu_defconfig @@ -277,7 +277,6 @@ CONFIG_TOUCHSCREEN_SYN_RMI4_SPI=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y -CONFIG_INPUT_CAPELLA_CM3217=y CONFIG_SERIO_LIBPS2=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set @@ -311,6 +310,7 @@ CONFIG_BATTERY_MAX17048=y CONFIG_CHARGER_GPIO=y CONFIG_SENSORS_TEGRA_TSENSOR=y CONFIG_SENSORS_INA219=y +CONFIG_SENSORS_CM3217=y CONFIG_THERMAL=y CONFIG_MFD_TPS6586X=y CONFIG_MFD_TPS65910=y diff --git a/arch/arm/configs/tegra_dalmore_mods_defconfig b/arch/arm/configs/tegra_dalmore_mods_defconfig index 15b7ac876b1e..99c9129d1be8 100644 --- a/arch/arm/configs/tegra_dalmore_mods_defconfig +++ b/arch/arm/configs/tegra_dalmore_mods_defconfig @@ -109,7 +109,6 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y -CONFIG_INPUT_CAPELLA_CM3217=y CONFIG_INV_AK8975=m CONFIG_INV_MPU=m CONFIG_SERIO_LIBPS2=y @@ -141,6 +140,7 @@ CONFIG_CHARGER_SMB349=y CONFIG_BATTERY_MAX17048=y CONFIG_CHARGER_GPIO=y CONFIG_SENSORS_INA219=y +CONFIG_SENSORS_CM3217=y CONFIG_THERMAL=y CONFIG_MFD_TPS6586X=y CONFIG_MFD_TPS65910=y diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index c2a302983440..5a3806c2f02d 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -631,12 +631,6 @@ config INPUT_ALPS_GPIO_SCROLLWHEEL To compile this driver as a module, choose M here: the module will be called alps_gpio_scrollwheel. -config INPUT_CAPELLA_CM3217 - tristate "CM3217 light sensor" - depends on I2C - help - Say Y here to enable the CM3217 Ambient Light Sensor. - config INPUT_CAPELLA_CM3218 tristate "CM3218 light sensor" depends on I2C diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a4e6d7d636e3..f0a7ccc6783b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -18,7 +18,6 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o obj-$(CONFIG_INPUT_BMA150) += bma150.o -obj-$(CONFIG_INPUT_CAPELLA_CM3217) += cm3217.o obj-$(CONFIG_INPUT_CAPELLA_CM3218) += cm3218.o obj-$(CONFIG_INPUT_CM109) += cm109.o obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index cba361ff98d8..5bc12d63eff7 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -50,4 +50,11 @@ config SENSORS_LTR558 If you say yes here you get support for ambient light sensing and proximity ir sensing from Lite On Technology LTR558. +config SENSORS_CM3217 + tristate "CM3217 light sensor" + depends on I2C + default n + help + Say Y here to enable the CM3217 Ambient Light Sensor. + endmenu diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 0590ac51fd2a..23a02521fb53 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o obj-$(CONFIG_TSL2583) += tsl2583.o obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_SENSORS_LTR558) += ltr558als.o +obj-$(CONFIG_SENSORS_CM3217) += cm3217.o diff --git a/drivers/input/misc/cm3217.c b/drivers/staging/iio/light/cm3217.c index 2d4f23364ed8..6ead6e2c7852 100644 --- a/drivers/input/misc/cm3217.c +++ b/drivers/staging/iio/light/cm3217.c @@ -3,7 +3,7 @@ * Copyright (C) 2011 Capella Microsystems Inc. * Author: Frank Hsieh <pengyueh@gmail.com> * - * Copyright (c) 2012, NVIDIA Corporation. + * Copyright (c) 2012-2013, NVIDIA CORPORATION. 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 @@ -56,7 +56,7 @@ struct cm3217_info { int als_enable; int als_enabled_before_suspend; - uint16_t *adc_table; + u32 *adc_table; uint16_t cali_table[10]; int irq; int ls_calibrate; @@ -70,6 +70,15 @@ struct cm3217_info { int current_level; uint16_t current_adc; int polling_delay; + + struct mutex enable_lock; + struct mutex disable_lock; + struct mutex get_adc_lock; +}; + +static struct cm3217_platform_data cm3217_dflt_pdata = { + .levels = {10, 160, 225, 320, 640, 1280, 2600, 5800, 8000, 10240}, + .golden_adc = 0, }; struct cm3217_info *lp_info; @@ -77,8 +86,6 @@ struct cm3217_info *lp_info; int enable_log; int fLevel = -1; -static struct mutex als_enable_mutex, als_disable_mutex, als_get_adc_mutex; - static int lightsensor_enable(struct cm3217_info *lpi); static int lightsensor_disable(struct cm3217_info *lpi); @@ -234,7 +241,7 @@ static void report_lsensor_input_event(struct cm3217_info *lpi, bool resume) uint16_t adc_value = 0; int level = 0, i, ret = 0; - mutex_lock(&als_get_adc_mutex); + mutex_lock(&lpi->get_adc_lock); ret = get_ls_adc_value(&adc_value, resume); @@ -293,7 +300,7 @@ static void report_lsensor_input_event(struct cm3217_info *lpi, bool resume) input_report_abs(lpi->ls_input_dev, ABS_MISC, level); input_sync(lpi->ls_input_dev); - mutex_unlock(&als_get_adc_mutex); + mutex_unlock(&lpi->get_adc_lock); } static void report_do_work(struct work_struct *work) @@ -372,7 +379,7 @@ static int lightsensor_enable(struct cm3217_info *lpi) int ret = 0; uint8_t cmd = 0; - mutex_lock(&als_enable_mutex); + mutex_lock(&lpi->enable_lock); D("[LS][CM3217] %s\n", __func__); @@ -386,7 +393,7 @@ static int lightsensor_enable(struct cm3217_info *lpi) queue_work(lpi->lp_wq, &report_work); lpi->als_enable = 1; - mutex_unlock(&als_enable_mutex); + mutex_unlock(&lpi->enable_lock); return ret; } @@ -396,7 +403,7 @@ static int lightsensor_disable(struct cm3217_info *lpi) int ret = 0; char cmd = 0; - mutex_lock(&als_disable_mutex); + mutex_lock(&lpi->disable_lock); D("[LS][CM3217] %s\n", __func__); @@ -413,7 +420,7 @@ static int lightsensor_disable(struct cm3217_info *lpi) cancel_delayed_work(&report_work); lpi->als_enable = 0; - mutex_unlock(&als_disable_mutex); + mutex_unlock(&lpi->disable_lock); return ret; } @@ -591,7 +598,7 @@ static ssize_t ls_kadc_store(struct device *dev, return -EINVAL; } */ - mutex_lock(&als_get_adc_mutex); + mutex_lock(&lpi->get_adc_lock); if (kadc_temp != 0) { lpi->als_kadc = kadc_temp; @@ -610,7 +617,7 @@ static ssize_t ls_kadc_store(struct device *dev, __func__); } - mutex_unlock(&als_get_adc_mutex); + mutex_unlock(&lpi->get_adc_lock); return count; } @@ -644,7 +651,7 @@ static ssize_t ls_gadc_store(struct device *dev, return -EINVAL; } */ - mutex_lock(&als_get_adc_mutex); + mutex_lock(&lpi->get_adc_lock); if (gadc_temp != 0) { lpi->als_gadc = gadc_temp; @@ -663,7 +670,7 @@ static ssize_t ls_gadc_store(struct device *dev, __func__); } - mutex_unlock(&als_get_adc_mutex); + mutex_unlock(&lpi->get_adc_lock); return count; } @@ -710,7 +717,7 @@ static ssize_t ls_adc_table_store(struct device *dev, } } - mutex_lock(&als_get_adc_mutex); + mutex_lock(&lpi->get_adc_lock); for (i = 0; i < 10; i++) { lpi->adc_table[i] = tempdata[i]; @@ -722,7 +729,7 @@ static ssize_t ls_adc_table_store(struct device *dev, printk(KERN_ERR "[LS][CM3217 error] %s: update ls table fail\n", __func__); - mutex_unlock(&als_get_adc_mutex); + mutex_unlock(&lpi->get_adc_lock); D("[LS][CM3217] %s\n", __func__); @@ -895,6 +902,47 @@ static int cm3217_setup(struct cm3217_info *lpi) return ret; } +static struct cm3217_platform_data *cm3217_parse_dt(struct i2c_client *client) +{ + struct cm3217_platform_data *pdata; + struct device_node *np = client->dev.of_node; + int err; + + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(&client->dev, "Can't allocate platform data\n"); + return ERR_PTR(-ENOMEM); + } + + if (!of_find_property(np, "levels", NULL)) { + memcpy(pdata->levels, cm3217_dflt_pdata.levels, + sizeof(pdata->levels)); + } else { + err = of_property_read_u32_array(np, "levels", + pdata->levels, CM3217_NUM_LEVELS); + if (err < 0) { + pr_err("%s: levels property read err(%d)", + __func__, err); + return ERR_PTR(err); + } + } + + if (!of_find_property(np, "golden_adc", NULL)) { + pdata->golden_adc = cm3217_dflt_pdata.golden_adc; + } else { + err = of_property_read_u32(np, "golden_adc", &pdata->golden_adc); + if (err < 0) { + pr_err("%s: golden_adc property read err(%d)", + __func__, err); + return ERR_PTR(err); + } + } + + pdata->power = NULL; /* FIXME */ + + return pdata; +} + static int cm3217_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -911,8 +959,17 @@ static int cm3217_probe(struct i2c_client *client, /* D("[CM3217] %s: client->irq = %d\n", __func__, client->irq); */ lpi->i2c_client = client; - pdata = client->dev.platform_data; - if (!pdata) { + if (client->dev.of_node) { + pdata = cm3217_parse_dt(client); + if (IS_ERR(pdata)) { + pr_err("[CM3217 error]%s: Assign platform_data error!!\n", + __func__); + ret = (int)pdata; + goto err_platform_data_null; + } + } else if (client->dev.platform_data) + pdata = client->dev.platform_data; + else { pr_err("[CM3217 error]%s: Assign platform_data error!!\n", __func__); ret = -EBUSY; @@ -930,9 +987,9 @@ static int cm3217_probe(struct i2c_client *client, lp_info = lpi; - mutex_init(&als_enable_mutex); - mutex_init(&als_disable_mutex); - mutex_init(&als_get_adc_mutex); + mutex_init(&lpi->enable_lock); + mutex_init(&lpi->disable_lock); + mutex_init(&lpi->get_adc_lock); ret = lightsensor_setup(lpi); if (ret < 0) { @@ -1038,9 +1095,9 @@ err_create_ls_device: err_create_class: err_cm3217_setup: destroy_workqueue(lpi->lp_wq); - mutex_destroy(&als_enable_mutex); - mutex_destroy(&als_disable_mutex); - mutex_destroy(&als_get_adc_mutex); + mutex_destroy(&lpi->enable_lock); + mutex_destroy(&lpi->disable_lock); + mutex_destroy(&lpi->get_adc_lock); input_unregister_device(lpi->ls_input_dev); input_free_device(lpi->ls_input_dev); err_create_singlethread_workqueue: @@ -1052,32 +1109,52 @@ err_platform_data_null: return ret; } +static int __devexit cm3217_remove(struct i2c_client *client) +{ + struct cm3217_info *lpi = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "%s()\n", __func__); + device_unregister(lpi->ls_dev); + class_destroy(lpi->cm3217_class); + destroy_workqueue(lpi->lp_wq); + mutex_destroy(&lpi->enable_lock); + mutex_destroy(&lpi->disable_lock); + mutex_destroy(&lpi->get_adc_lock); + input_unregister_device(lpi->ls_input_dev); + input_free_device(lpi->ls_input_dev); + misc_deregister(&lightsensor_misc); + kfree(lpi); + + return 0; +} + static const struct i2c_device_id cm3217_i2c_id[] = { - {CM3217_I2C_NAME, 0}, + {"cm3217", 0}, {} }; +MODULE_DEVICE_TABLE(i2c, cm3217_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id cm3217_of_match[] = { + { .compatible = "capella,cm3217", }, + { }, +}; +MODULE_DEVICE_TABLE(of, cm3217_of_match); +#endif + static struct i2c_driver cm3217_driver = { - .id_table = cm3217_i2c_id, + .class = I2C_CLASS_HWMON, .probe = cm3217_probe, + .remove = __devexit_p(cm3217_remove), .driver = { - .name = CM3217_I2C_NAME, + .name = "cm3217", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(cm3217_of_match), }, + .id_table = cm3217_i2c_id, }; - -static int __init cm3217_init(void) -{ - return i2c_add_driver(&cm3217_driver); -} - -static void __exit cm3217_exit(void) -{ - i2c_del_driver(&cm3217_driver); -} - -module_init(cm3217_init); -module_exit(cm3217_exit); +module_i2c_driver(cm3217_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CM3217 Driver"); diff --git a/include/linux/cm3217.h b/include/linux/cm3217.h index 29c72b58f8e7..9b51477478fa 100644 --- a/include/linux/cm3217.h +++ b/include/linux/cm3217.h @@ -1,6 +1,7 @@ /* include/linux/cm3217.h * * Copyright (C) 2011 Capella Microsystems Inc. + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. * Author: Frank Hsieh <pengyueh@gmail.com> * * This software is licensed under the terms of the GNU General Public @@ -47,9 +48,11 @@ #define CM3217_ALS_IT_80ms (6 << 5) #define CM3217_ALS_IT_66ms (7 << 5) +#define CM3217_NUM_LEVELS 10 + struct cm3217_platform_data { - uint16_t levels[10]; - uint16_t golden_adc; + u32 levels[CM3217_NUM_LEVELS]; + u32 golden_adc; int (*power) (int, uint8_t); /* power to the chip */ uint16_t ALS_slave_address; }; |