aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/light
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 20:37:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 20:37:33 -0400
commitb79013b2449c23f1f505bdf39c5a6c330338b244 (patch)
tree67908ffb1705a595cda8de7224d121fa40b8f36d /drivers/iio/light
parentc4be50eee2bd4d50e0f0ca58776f685c08de69c3 (diff)
parentc610f7f772aa06ae2bd8e5ace87cde4d90f70198 (diff)
Merge tag 'staging-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here's the big staging driver patchset for 4.1-rc1. There's a lot of patches here, the Outreachy application period happened during this development cycle, so that means that there was a lot of cleanup patches accepted. Other than the normal coding style and sparse fixes here, there are some driver updates and work toward making some of the drivers into "mergable" shape (like the Unisys drivers.) All of these have been in linux-next for a while" * tag 'staging-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1214 commits) staging: lustre: orthography & coding style staging: lustre: lnet: lnet: fix error return code staging: lustre: fix sparse warning Revert "Staging: sm750fb: Fix C99 Comments" Staging: rtl8192u: use correct array for debug output staging: rtl8192e: Remove dead code staging: rtl8192e: Comment cleanup (style/format) staging: rtl8192e: Fix indentation in rtllib_rx_auth_resp() staging: rtl8192e: Decrease nesting of rtllib_rx_auth_resp() staging: rtl8192e: Divide rtllib_rx_auth() staging: rtl8192e: Fix PRINTK_WITHOUT_KERN_LEVEL warnings staging: rtl8192e: Fix DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON warning staging: rtl8192e: Fix BRACES warning staging: rtl8192e: Fix LINE_CONTINUATIONS warning staging: rtl8192e: Fix UNNECESSARY_PARENTHESES warnings staging: rtl8192e: remove unused EXPORT_SYMBOL_RSL macro staging: rtl8192e: Fix RETURN_VOID warnings staging: rtl8192e: Fix UNNECESSARY_ELSE warning staging: rtl8723au: Remove unneeded comments staging: rtl8723au: Use __func__ in trace logs ...
Diffstat (limited to 'drivers/iio/light')
-rw-r--r--drivers/iio/light/Kconfig10
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/cm3232.c36
-rw-r--r--drivers/iio/light/cm3323.c286
-rw-r--r--drivers/iio/light/gp2ap020a00f.c6
-rw-r--r--drivers/iio/light/jsa1212.c2
-rw-r--r--drivers/iio/light/ltr501.c18
7 files changed, 347 insertions, 12 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index a224afd6380c..01a1a16ab7be 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -59,6 +59,16 @@ config CM3232
59 To compile this driver as a module, choose M here: 59 To compile this driver as a module, choose M here:
60 the module will be called cm3232. 60 the module will be called cm3232.
61 61
62config CM3323
63 depends on I2C
64 tristate "Capella CM3323 color light sensor"
65 help
66 Say Y here if you want to build a driver for Capela CM3323
67 color sensor.
68
69 To compile this driver as a module, choose M here: the module will
70 be called cm3323.
71
62config CM36651 72config CM36651
63 depends on I2C 73 depends on I2C
64 tristate "CM36651 driver" 74 tristate "CM36651 driver"
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index b12a5160d9e0..ad7c30fe443b 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_AL3320A) += al3320a.o
8obj-$(CONFIG_APDS9300) += apds9300.o 8obj-$(CONFIG_APDS9300) += apds9300.o
9obj-$(CONFIG_CM32181) += cm32181.o 9obj-$(CONFIG_CM32181) += cm32181.o
10obj-$(CONFIG_CM3232) += cm3232.o 10obj-$(CONFIG_CM3232) += cm3232.o
11obj-$(CONFIG_CM3323) += cm3323.o
11obj-$(CONFIG_CM36651) += cm36651.o 12obj-$(CONFIG_CM36651) += cm36651.o
12obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o 13obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
13obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o 14obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c
index 90e3519a91de..39c8d99cc48e 100644
--- a/drivers/iio/light/cm3232.c
+++ b/drivers/iio/light/cm3232.c
@@ -378,6 +378,39 @@ static const struct i2c_device_id cm3232_id[] = {
378 {} 378 {}
379}; 379};
380 380
381#ifdef CONFIG_PM_SLEEP
382static int cm3232_suspend(struct device *dev)
383{
384 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
385 struct cm3232_chip *chip = iio_priv(indio_dev);
386 struct i2c_client *client = chip->client;
387 int ret;
388
389 chip->regs_cmd |= CM3232_CMD_ALS_DISABLE;
390 ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
391 chip->regs_cmd);
392
393 return ret;
394}
395
396static int cm3232_resume(struct device *dev)
397{
398 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
399 struct cm3232_chip *chip = iio_priv(indio_dev);
400 struct i2c_client *client = chip->client;
401 int ret;
402
403 chip->regs_cmd &= ~CM3232_CMD_ALS_DISABLE;
404 ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
405 chip->regs_cmd | CM3232_CMD_ALS_RESET);
406
407 return ret;
408}
409
410static const struct dev_pm_ops cm3232_pm_ops = {
411 SET_SYSTEM_SLEEP_PM_OPS(cm3232_suspend, cm3232_resume)};
412#endif
413
381MODULE_DEVICE_TABLE(i2c, cm3232_id); 414MODULE_DEVICE_TABLE(i2c, cm3232_id);
382 415
383static const struct of_device_id cm3232_of_match[] = { 416static const struct of_device_id cm3232_of_match[] = {
@@ -390,6 +423,9 @@ static struct i2c_driver cm3232_driver = {
390 .name = "cm3232", 423 .name = "cm3232",
391 .owner = THIS_MODULE, 424 .owner = THIS_MODULE,
392 .of_match_table = of_match_ptr(cm3232_of_match), 425 .of_match_table = of_match_ptr(cm3232_of_match),
426#ifdef CONFIG_PM_SLEEP
427 .pm = &cm3232_pm_ops,
428#endif
393 }, 429 },
394 .id_table = cm3232_id, 430 .id_table = cm3232_id,
395 .probe = cm3232_probe, 431 .probe = cm3232_probe,
diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c
new file mode 100644
index 000000000000..869033e48a1f
--- /dev/null
+++ b/drivers/iio/light/cm3323.c
@@ -0,0 +1,286 @@
1/*
2 * CM3323 - Capella Color Light Sensor
3 *
4 * Copyright (c) 2015, Intel Corporation.
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * IIO driver for CM3323 (7-bit I2C slave address 0x10)
11 *
12 * TODO: calibscale to correct the lens factor
13 */
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/mutex.h>
18
19#include <linux/iio/iio.h>
20#include <linux/iio/sysfs.h>
21
22#define CM3323_DRV_NAME "cm3323"
23
24#define CM3323_CMD_CONF 0x00
25#define CM3323_CMD_RED_DATA 0x08
26#define CM3323_CMD_GREEN_DATA 0x09
27#define CM3323_CMD_BLUE_DATA 0x0A
28#define CM3323_CMD_CLEAR_DATA 0x0B
29
30#define CM3323_CONF_SD_BIT BIT(0) /* sensor disable */
31#define CM3323_CONF_AF_BIT BIT(1) /* auto/manual force mode */
32#define CM3323_CONF_IT_MASK (BIT(4) | BIT(5) | BIT(6))
33#define CM3323_CONF_IT_SHIFT 4
34
35#define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"
36
37static const struct {
38 int val;
39 int val2;
40} cm3323_int_time[] = {
41 {0, 40000}, /* 40 ms */
42 {0, 80000}, /* 80 ms */
43 {0, 160000}, /* 160 ms */
44 {0, 320000}, /* 320 ms */
45 {0, 640000}, /* 640 ms */
46 {1, 280000}, /* 1280 ms */
47};
48
49struct cm3323_data {
50 struct i2c_client *client;
51 u16 reg_conf;
52 struct mutex mutex;
53};
54
55#define CM3323_COLOR_CHANNEL(_color, _addr) { \
56 .type = IIO_INTENSITY, \
57 .modified = 1, \
58 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
59 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), \
60 .channel2 = IIO_MOD_LIGHT_##_color, \
61 .address = _addr, \
62}
63
64static const struct iio_chan_spec cm3323_channels[] = {
65 CM3323_COLOR_CHANNEL(RED, CM3323_CMD_RED_DATA),
66 CM3323_COLOR_CHANNEL(GREEN, CM3323_CMD_GREEN_DATA),
67 CM3323_COLOR_CHANNEL(BLUE, CM3323_CMD_BLUE_DATA),
68 CM3323_COLOR_CHANNEL(CLEAR, CM3323_CMD_CLEAR_DATA),
69};
70
71static IIO_CONST_ATTR_INT_TIME_AVAIL(CM3323_INT_TIME_AVAILABLE);
72
73static struct attribute *cm3323_attributes[] = {
74 &iio_const_attr_integration_time_available.dev_attr.attr,
75 NULL
76};
77
78static const struct attribute_group cm3323_attribute_group = {
79 .attrs = cm3323_attributes,
80};
81
82static int cm3323_init(struct iio_dev *indio_dev)
83{
84 int ret;
85 struct cm3323_data *data = iio_priv(indio_dev);
86
87 ret = i2c_smbus_read_word_data(data->client, CM3323_CMD_CONF);
88 if (ret < 0) {
89 dev_err(&data->client->dev, "Error reading reg_conf\n");
90 return ret;
91 }
92
93 /* enable sensor and set auto force mode */
94 ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);
95
96 ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
97 if (ret < 0) {
98 dev_err(&data->client->dev, "Error writing reg_conf\n");
99 return ret;
100 }
101
102 data->reg_conf = ret;
103
104 return 0;
105}
106
107static void cm3323_disable(struct iio_dev *indio_dev)
108{
109 int ret;
110 struct cm3323_data *data = iio_priv(indio_dev);
111
112 ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF,
113 CM3323_CONF_SD_BIT);
114 if (ret < 0)
115 dev_err(&data->client->dev, "Error writing reg_conf\n");
116}
117
118static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2)
119{
120 int i, ret;
121 u16 reg_conf;
122
123 for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) {
124 if (val == cm3323_int_time[i].val &&
125 val2 == cm3323_int_time[i].val2) {
126 reg_conf = data->reg_conf;
127 reg_conf |= i << CM3323_CONF_IT_SHIFT;
128
129 ret = i2c_smbus_write_word_data(data->client,
130 CM3323_CMD_CONF,
131 reg_conf);
132 if (ret < 0)
133 return ret;
134
135 data->reg_conf = reg_conf;
136 return 0;
137 }
138 }
139 return -EINVAL;
140}
141
142static int cm3323_get_it_bits(struct cm3323_data *data)
143{
144 int bits;
145
146 bits = (data->reg_conf & CM3323_CONF_IT_MASK) >>
147 CM3323_CONF_IT_SHIFT;
148
149 if (bits >= ARRAY_SIZE(cm3323_int_time))
150 return -EINVAL;
151 return bits;
152}
153
154static int cm3323_read_raw(struct iio_dev *indio_dev,
155 struct iio_chan_spec const *chan, int *val,
156 int *val2, long mask)
157{
158 int i, ret;
159 struct cm3323_data *data = iio_priv(indio_dev);
160
161 switch (mask) {
162 case IIO_CHAN_INFO_RAW:
163 mutex_lock(&data->mutex);
164 ret = i2c_smbus_read_word_data(data->client, chan->address);
165 if (ret < 0) {
166 mutex_unlock(&data->mutex);
167 return ret;
168 }
169 *val = ret;
170 mutex_unlock(&data->mutex);
171
172 return IIO_VAL_INT;
173 case IIO_CHAN_INFO_INT_TIME:
174 mutex_lock(&data->mutex);
175 i = cm3323_get_it_bits(data);
176 if (i < 0) {
177 mutex_unlock(&data->mutex);
178 return -EINVAL;
179 }
180
181 *val = cm3323_int_time[i].val;
182 *val2 = cm3323_int_time[i].val2;
183 mutex_unlock(&data->mutex);
184
185 return IIO_VAL_INT_PLUS_MICRO;
186 default:
187 return -EINVAL;
188 }
189}
190
191static int cm3323_write_raw(struct iio_dev *indio_dev,
192 struct iio_chan_spec const *chan, int val,
193 int val2, long mask)
194{
195 struct cm3323_data *data = iio_priv(indio_dev);
196 int ret;
197
198 switch (mask) {
199 case IIO_CHAN_INFO_INT_TIME:
200 mutex_lock(&data->mutex);
201 ret = cm3323_set_it_bits(data, val, val2);
202 mutex_unlock(&data->mutex);
203
204 return ret;
205 default:
206 return -EINVAL;
207 }
208}
209
210static const struct iio_info cm3323_info = {
211 .driver_module = THIS_MODULE,
212 .read_raw = cm3323_read_raw,
213 .write_raw = cm3323_write_raw,
214 .attrs = &cm3323_attribute_group,
215};
216
217static int cm3323_probe(struct i2c_client *client,
218 const struct i2c_device_id *id)
219{
220 struct cm3323_data *data;
221 struct iio_dev *indio_dev;
222 int ret;
223
224 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
225 if (!indio_dev)
226 return -ENOMEM;
227
228 data = iio_priv(indio_dev);
229 i2c_set_clientdata(client, indio_dev);
230 data->client = client;
231
232 mutex_init(&data->mutex);
233
234 indio_dev->dev.parent = &client->dev;
235 indio_dev->info = &cm3323_info;
236 indio_dev->name = CM3323_DRV_NAME;
237 indio_dev->channels = cm3323_channels;
238 indio_dev->num_channels = ARRAY_SIZE(cm3323_channels);
239 indio_dev->modes = INDIO_DIRECT_MODE;
240
241 ret = cm3323_init(indio_dev);
242 if (ret < 0) {
243 dev_err(&client->dev, "cm3323 chip init failed\n");
244 return ret;
245 }
246 ret = iio_device_register(indio_dev);
247 if (ret < 0) {
248 dev_err(&client->dev, "failed to register iio dev\n");
249 goto err_init;
250 }
251 return 0;
252err_init:
253 cm3323_disable(indio_dev);
254 return ret;
255}
256
257static int cm3323_remove(struct i2c_client *client)
258{
259 struct iio_dev *indio_dev = i2c_get_clientdata(client);
260
261 iio_device_unregister(indio_dev);
262 cm3323_disable(indio_dev);
263
264 return 0;
265}
266
267static const struct i2c_device_id cm3323_id[] = {
268 {"cm3323", 0},
269 {}
270};
271MODULE_DEVICE_TABLE(i2c, cm3323_id);
272
273static struct i2c_driver cm3323_driver = {
274 .driver = {
275 .name = CM3323_DRV_NAME,
276 },
277 .probe = cm3323_probe,
278 .remove = cm3323_remove,
279 .id_table = cm3323_id,
280};
281
282module_i2c_driver(cm3323_driver);
283
284MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
285MODULE_DESCRIPTION("Capella CM3323 Color Light Sensor driver");
286MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
index 221ed16de1f7..32b6449833fa 100644
--- a/drivers/iio/light/gp2ap020a00f.c
+++ b/drivers/iio/light/gp2ap020a00f.c
@@ -46,6 +46,7 @@
46#include <linux/regmap.h> 46#include <linux/regmap.h>
47#include <linux/regulator/consumer.h> 47#include <linux/regulator/consumer.h>
48#include <linux/slab.h> 48#include <linux/slab.h>
49#include <asm/unaligned.h>
49#include <linux/iio/buffer.h> 50#include <linux/iio/buffer.h>
50#include <linux/iio/events.h> 51#include <linux/iio/events.h>
51#include <linux/iio/iio.h> 52#include <linux/iio/iio.h>
@@ -966,7 +967,6 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
966 struct iio_dev *indio_dev = pf->indio_dev; 967 struct iio_dev *indio_dev = pf->indio_dev;
967 struct gp2ap020a00f_data *priv = iio_priv(indio_dev); 968 struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
968 size_t d_size = 0; 969 size_t d_size = 0;
969 __le32 light_lux;
970 int i, out_val, ret; 970 int i, out_val, ret;
971 971
972 for_each_set_bit(i, indio_dev->active_scan_mask, 972 for_each_set_bit(i, indio_dev->active_scan_mask,
@@ -981,8 +981,8 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
981 i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) { 981 i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) {
982 out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]); 982 out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]);
983 gp2ap020a00f_output_to_lux(priv, &out_val); 983 gp2ap020a00f_output_to_lux(priv, &out_val);
984 light_lux = cpu_to_le32(out_val); 984
985 memcpy(&priv->buffer[d_size], (u8 *)&light_lux, 4); 985 put_unaligned_le32(out_val, &priv->buffer[d_size]);
986 d_size += 4; 986 d_size += 4;
987 } else { 987 } else {
988 d_size += 2; 988 d_size += 2;
diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c
index 29de7e7d9562..3a3af89beaf9 100644
--- a/drivers/iio/light/jsa1212.c
+++ b/drivers/iio/light/jsa1212.c
@@ -308,7 +308,7 @@ static bool jsa1212_is_volatile_reg(struct device *dev, unsigned int reg)
308 } 308 }
309} 309}
310 310
311static struct regmap_config jsa1212_regmap_config = { 311static const struct regmap_config jsa1212_regmap_config = {
312 .name = JSA1212_REGMAP_NAME, 312 .name = JSA1212_REGMAP_NAME,
313 .reg_bits = 8, 313 .reg_bits = 8,
314 .val_bits = 8, 314 .val_bits = 8,
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 62b7072af4de..78b87839c4b9 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -333,6 +333,13 @@ static int ltr501_init(struct ltr501_data *data)
333 data->ps_contr); 333 data->ps_contr);
334} 334}
335 335
336static int ltr501_powerdown(struct ltr501_data *data)
337{
338 return ltr501_write_contr(data->client,
339 data->als_contr & ~LTR501_CONTR_ACTIVE,
340 data->ps_contr & ~LTR501_CONTR_ACTIVE);
341}
342
336static int ltr501_probe(struct i2c_client *client, 343static int ltr501_probe(struct i2c_client *client,
337 const struct i2c_device_id *id) 344 const struct i2c_device_id *id)
338{ 345{
@@ -370,7 +377,7 @@ static int ltr501_probe(struct i2c_client *client,
370 ret = iio_triggered_buffer_setup(indio_dev, NULL, 377 ret = iio_triggered_buffer_setup(indio_dev, NULL,
371 ltr501_trigger_handler, NULL); 378 ltr501_trigger_handler, NULL);
372 if (ret) 379 if (ret)
373 return ret; 380 goto powerdown_on_error;
374 381
375 ret = iio_device_register(indio_dev); 382 ret = iio_device_register(indio_dev);
376 if (ret) 383 if (ret)
@@ -380,16 +387,11 @@ static int ltr501_probe(struct i2c_client *client,
380 387
381error_unreg_buffer: 388error_unreg_buffer:
382 iio_triggered_buffer_cleanup(indio_dev); 389 iio_triggered_buffer_cleanup(indio_dev);
390powerdown_on_error:
391 ltr501_powerdown(data);
383 return ret; 392 return ret;
384} 393}
385 394
386static int ltr501_powerdown(struct ltr501_data *data)
387{
388 return ltr501_write_contr(data->client,
389 data->als_contr & ~LTR501_CONTR_ACTIVE,
390 data->ps_contr & ~LTR501_CONTR_ACTIVE);
391}
392
393static int ltr501_remove(struct i2c_client *client) 395static int ltr501_remove(struct i2c_client *client)
394{ 396{
395 struct iio_dev *indio_dev = i2c_get_clientdata(client); 397 struct iio_dev *indio_dev = i2c_get_clientdata(client);