diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:57 -0400 |
commit | 751144271f4b63d5de9005ea4e5e6e5c7c6fd629 (patch) | |
tree | 2e5cb8223d4f6146f01f123a9f33cf6d468205c6 /drivers/iio/light | |
parent | 542a086ac72fb193cbc1b996963a572269e57743 (diff) | |
parent | 91121c103ae93ef117e58712786864270d7f488e (diff) |
Merge tag 'staging-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree merge from Greg KH:
"Here's the bit staging tree pull request for 3.12-rc1.
Lots of staging driver updates, and fixes. Lustre is finally enabled
in the build, and lots of cleanup started happening in it. There's a
new wireless driver in here, and 2 new TTY drivers, which cause the
overall lines added/removed to be quite large on the "added" side.
The IIO driver updates are also coming through here, as they are tied
to the staging iio drivers"
* tag 'staging-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (942 commits)
staging: dwc2: make dwc2_core_params documentation more complete
staging: dwc2: validate the value for phy_utmi_width
staging: dwc2: interpret all hwcfg and related register at init time
staging: dwc2: properly mask the GRXFSIZ register
staging: dwc2: remove redundant register reads
staging: dwc2: re-use hptxfsiz variable
staging: dwc2: simplify debug output in dwc_hc_init
staging: dwc2: add missing shift
staging: dwc2: simplify register shift expressions
staging: dwc2: only read the snpsid register once
staging: dwc2: unshift non-bool register value constants
staging: dwc2: fix off-by-one in check for max_packet_count parameter
staging: dwc2: remove specific fifo size constants
Staging:BCM:DDRInit.c:Renaming __FUNCTION__
staging: bcm: remove Version.h file.
staging: rtl8188eu: off by one in rtw_set_802_11_add_wep()
staging: r8188eu: copying one byte too much
staging: rtl8188eu: || vs && typo
staging: r8188eu: off by one bugs
staging: crystalhd: Resolve sparse 'different base types' warnings.
...
Diffstat (limited to 'drivers/iio/light')
-rw-r--r-- | drivers/iio/light/Kconfig | 34 | ||||
-rw-r--r-- | drivers/iio/light/Makefile | 4 | ||||
-rw-r--r-- | drivers/iio/light/adjd_s311.c | 43 | ||||
-rw-r--r-- | drivers/iio/light/apds9300.c | 512 | ||||
-rw-r--r-- | drivers/iio/light/hid-sensor-als.c | 41 | ||||
-rw-r--r-- | drivers/iio/light/lm3533-als.c | 7 | ||||
-rw-r--r-- | drivers/iio/light/tsl2563.c | 25 | ||||
-rw-r--r-- | drivers/iio/light/vcnl4000.c | 16 |
8 files changed, 583 insertions, 99 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 5ef1a396e0c9..bf9fa0d7aff9 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
@@ -1,6 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Light sensors | 2 | # Light sensors |
3 | # | 3 | # |
4 | # When adding new entries keep the list in alphabetical order | ||
5 | |||
4 | menu "Light sensors" | 6 | menu "Light sensors" |
5 | 7 | ||
6 | config ADJD_S311 | 8 | config ADJD_S311 |
@@ -15,6 +17,27 @@ config ADJD_S311 | |||
15 | This driver can also be built as a module. If so, the module | 17 | This driver can also be built as a module. If so, the module |
16 | will be called adjd_s311. | 18 | will be called adjd_s311. |
17 | 19 | ||
20 | config APDS9300 | ||
21 | tristate "APDS9300 ambient light sensor" | ||
22 | depends on I2C | ||
23 | help | ||
24 | Say Y here if you want to build a driver for the Avago APDS9300 | ||
25 | ambient light sensor. | ||
26 | |||
27 | To compile this driver as a module, choose M here: the | ||
28 | module will be called apds9300. | ||
29 | |||
30 | config HID_SENSOR_ALS | ||
31 | depends on HID_SENSOR_HUB | ||
32 | select IIO_BUFFER | ||
33 | select IIO_TRIGGERED_BUFFER | ||
34 | select HID_SENSOR_IIO_COMMON | ||
35 | select HID_SENSOR_IIO_TRIGGER | ||
36 | tristate "HID ALS" | ||
37 | help | ||
38 | Say yes here to build support for the HID SENSOR | ||
39 | Ambient light sensor. | ||
40 | |||
18 | config SENSORS_LM3533 | 41 | config SENSORS_LM3533 |
19 | tristate "LM3533 ambient light sensor" | 42 | tristate "LM3533 ambient light sensor" |
20 | depends on MFD_LM3533 | 43 | depends on MFD_LM3533 |
@@ -52,15 +75,4 @@ config VCNL4000 | |||
52 | To compile this driver as a module, choose M here: the | 75 | To compile this driver as a module, choose M here: the |
53 | module will be called vcnl4000. | 76 | module will be called vcnl4000. |
54 | 77 | ||
55 | config HID_SENSOR_ALS | ||
56 | depends on HID_SENSOR_HUB | ||
57 | select IIO_BUFFER | ||
58 | select IIO_TRIGGERED_BUFFER | ||
59 | select HID_SENSOR_IIO_COMMON | ||
60 | select HID_SENSOR_IIO_TRIGGER | ||
61 | tristate "HID ALS" | ||
62 | help | ||
63 | Say yes here to build support for the HID SENSOR | ||
64 | Ambient light sensor. | ||
65 | |||
66 | endmenu | 78 | endmenu |
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 040d9c75f8e6..354ee9ab2379 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile | |||
@@ -2,8 +2,10 @@ | |||
2 | # Makefile for IIO Light sensors | 2 | # Makefile for IIO Light sensors |
3 | # | 3 | # |
4 | 4 | ||
5 | # When adding new entries keep the list in alphabetical order | ||
5 | obj-$(CONFIG_ADJD_S311) += adjd_s311.o | 6 | obj-$(CONFIG_ADJD_S311) += adjd_s311.o |
7 | obj-$(CONFIG_APDS9300) += apds9300.o | ||
8 | obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o | ||
6 | obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o | 9 | obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o |
7 | obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o | 10 | obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o |
8 | obj-$(CONFIG_VCNL4000) += vcnl4000.o | 11 | obj-$(CONFIG_VCNL4000) += vcnl4000.o |
9 | obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o | ||
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index c1cd5698b8ae..23cff798598a 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c | |||
@@ -37,22 +37,14 @@ | |||
37 | #define ADJD_S311_CAP_GREEN 0x07 | 37 | #define ADJD_S311_CAP_GREEN 0x07 |
38 | #define ADJD_S311_CAP_BLUE 0x08 | 38 | #define ADJD_S311_CAP_BLUE 0x08 |
39 | #define ADJD_S311_CAP_CLEAR 0x09 | 39 | #define ADJD_S311_CAP_CLEAR 0x09 |
40 | #define ADJD_S311_INT_RED_LO 0x0a | 40 | #define ADJD_S311_INT_RED 0x0a |
41 | #define ADJD_S311_INT_RED_HI 0x0b | 41 | #define ADJD_S311_INT_GREEN 0x0c |
42 | #define ADJD_S311_INT_GREEN_LO 0x0c | 42 | #define ADJD_S311_INT_BLUE 0x0e |
43 | #define ADJD_S311_INT_GREEN_HI 0x0d | 43 | #define ADJD_S311_INT_CLEAR 0x10 |
44 | #define ADJD_S311_INT_BLUE_LO 0x0e | 44 | #define ADJD_S311_DATA_RED 0x40 |
45 | #define ADJD_S311_INT_BLUE_HI 0x0f | 45 | #define ADJD_S311_DATA_GREEN 0x42 |
46 | #define ADJD_S311_INT_CLEAR_LO 0x10 | 46 | #define ADJD_S311_DATA_BLUE 0x44 |
47 | #define ADJD_S311_INT_CLEAR_HI 0x11 | 47 | #define ADJD_S311_DATA_CLEAR 0x46 |
48 | #define ADJD_S311_DATA_RED_LO 0x40 | ||
49 | #define ADJD_S311_DATA_RED_HI 0x41 | ||
50 | #define ADJD_S311_DATA_GREEN_LO 0x42 | ||
51 | #define ADJD_S311_DATA_GREEN_HI 0x43 | ||
52 | #define ADJD_S311_DATA_BLUE_LO 0x44 | ||
53 | #define ADJD_S311_DATA_BLUE_HI 0x45 | ||
54 | #define ADJD_S311_DATA_CLEAR_LO 0x46 | ||
55 | #define ADJD_S311_DATA_CLEAR_HI 0x47 | ||
56 | #define ADJD_S311_OFFSET_RED 0x48 | 48 | #define ADJD_S311_OFFSET_RED 0x48 |
57 | #define ADJD_S311_OFFSET_GREEN 0x49 | 49 | #define ADJD_S311_OFFSET_GREEN 0x49 |
58 | #define ADJD_S311_OFFSET_BLUE 0x4a | 50 | #define ADJD_S311_OFFSET_BLUE 0x4a |
@@ -73,8 +65,8 @@ enum adjd_s311_channel_idx { | |||
73 | IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR | 65 | IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR |
74 | }; | 66 | }; |
75 | 67 | ||
76 | #define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED_LO + (chan) * 2) | 68 | #define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED + (chan) * 2) |
77 | #define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED_LO + (chan) * 2) | 69 | #define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED + (chan) * 2) |
78 | #define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan)) | 70 | #define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan)) |
79 | 71 | ||
80 | static int adjd_s311_req_data(struct iio_dev *indio_dev) | 72 | static int adjd_s311_req_data(struct iio_dev *indio_dev) |
@@ -294,11 +286,10 @@ static int adjd_s311_probe(struct i2c_client *client, | |||
294 | struct iio_dev *indio_dev; | 286 | struct iio_dev *indio_dev; |
295 | int err; | 287 | int err; |
296 | 288 | ||
297 | indio_dev = iio_device_alloc(sizeof(*data)); | 289 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); |
298 | if (indio_dev == NULL) { | 290 | if (indio_dev == NULL) |
299 | err = -ENOMEM; | 291 | return -ENOMEM; |
300 | goto exit; | 292 | |
301 | } | ||
302 | data = iio_priv(indio_dev); | 293 | data = iio_priv(indio_dev); |
303 | i2c_set_clientdata(client, indio_dev); | 294 | i2c_set_clientdata(client, indio_dev); |
304 | data->client = client; | 295 | data->client = client; |
@@ -313,7 +304,7 @@ static int adjd_s311_probe(struct i2c_client *client, | |||
313 | err = iio_triggered_buffer_setup(indio_dev, NULL, | 304 | err = iio_triggered_buffer_setup(indio_dev, NULL, |
314 | adjd_s311_trigger_handler, NULL); | 305 | adjd_s311_trigger_handler, NULL); |
315 | if (err < 0) | 306 | if (err < 0) |
316 | goto exit_free_device; | 307 | return err; |
317 | 308 | ||
318 | err = iio_device_register(indio_dev); | 309 | err = iio_device_register(indio_dev); |
319 | if (err) | 310 | if (err) |
@@ -325,9 +316,6 @@ static int adjd_s311_probe(struct i2c_client *client, | |||
325 | 316 | ||
326 | exit_unreg_buffer: | 317 | exit_unreg_buffer: |
327 | iio_triggered_buffer_cleanup(indio_dev); | 318 | iio_triggered_buffer_cleanup(indio_dev); |
328 | exit_free_device: | ||
329 | iio_device_free(indio_dev); | ||
330 | exit: | ||
331 | return err; | 319 | return err; |
332 | } | 320 | } |
333 | 321 | ||
@@ -339,7 +327,6 @@ static int adjd_s311_remove(struct i2c_client *client) | |||
339 | iio_device_unregister(indio_dev); | 327 | iio_device_unregister(indio_dev); |
340 | iio_triggered_buffer_cleanup(indio_dev); | 328 | iio_triggered_buffer_cleanup(indio_dev); |
341 | kfree(data->buffer); | 329 | kfree(data->buffer); |
342 | iio_device_free(indio_dev); | ||
343 | 330 | ||
344 | return 0; | 331 | return 0; |
345 | } | 332 | } |
diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c new file mode 100644 index 000000000000..66a58bda6dc8 --- /dev/null +++ b/drivers/iio/light/apds9300.c | |||
@@ -0,0 +1,512 @@ | |||
1 | /* | ||
2 | * apds9300.c - IIO driver for Avago APDS9300 ambient light sensor | ||
3 | * | ||
4 | * Copyright 2013 Oleksandr Kravchenko <o.v.kravchenko@globallogic.com> | ||
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 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/pm.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/mutex.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/iio/iio.h> | ||
19 | #include <linux/iio/sysfs.h> | ||
20 | #include <linux/iio/events.h> | ||
21 | |||
22 | #define APDS9300_DRV_NAME "apds9300" | ||
23 | #define APDS9300_IRQ_NAME "apds9300_event" | ||
24 | |||
25 | /* Command register bits */ | ||
26 | #define APDS9300_CMD BIT(7) /* Select command register. Must write as 1 */ | ||
27 | #define APDS9300_WORD BIT(5) /* I2C write/read: if 1 word, if 0 byte */ | ||
28 | #define APDS9300_CLEAR BIT(6) /* Interrupt clear. Clears pending interrupt */ | ||
29 | |||
30 | /* Register set */ | ||
31 | #define APDS9300_CONTROL 0x00 /* Control of basic functions */ | ||
32 | #define APDS9300_THRESHLOWLOW 0x02 /* Low byte of low interrupt threshold */ | ||
33 | #define APDS9300_THRESHHIGHLOW 0x04 /* Low byte of high interrupt threshold */ | ||
34 | #define APDS9300_INTERRUPT 0x06 /* Interrupt control */ | ||
35 | #define APDS9300_DATA0LOW 0x0c /* Low byte of ADC channel 0 */ | ||
36 | #define APDS9300_DATA1LOW 0x0e /* Low byte of ADC channel 1 */ | ||
37 | |||
38 | /* Power on/off value for APDS9300_CONTROL register */ | ||
39 | #define APDS9300_POWER_ON 0x03 | ||
40 | #define APDS9300_POWER_OFF 0x00 | ||
41 | |||
42 | /* Interrupts */ | ||
43 | #define APDS9300_INTR_ENABLE 0x10 | ||
44 | /* Interrupt Persist Function: Any value outside of threshold range */ | ||
45 | #define APDS9300_THRESH_INTR 0x01 | ||
46 | |||
47 | #define APDS9300_THRESH_MAX 0xffff /* Max threshold value */ | ||
48 | |||
49 | struct apds9300_data { | ||
50 | struct i2c_client *client; | ||
51 | struct mutex mutex; | ||
52 | int power_state; | ||
53 | int thresh_low; | ||
54 | int thresh_hi; | ||
55 | int intr_en; | ||
56 | }; | ||
57 | |||
58 | /* Lux calculation */ | ||
59 | |||
60 | /* Calculated values 1000 * (CH1/CH0)^1.4 for CH1/CH0 from 0 to 0.52 */ | ||
61 | static const u16 apds9300_lux_ratio[] = { | ||
62 | 0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91, | ||
63 | 98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203, | ||
64 | 212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337, | ||
65 | 347, 358, 368, 379, 390, 400, | ||
66 | }; | ||
67 | |||
68 | static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1) | ||
69 | { | ||
70 | unsigned long lux, tmp; | ||
71 | |||
72 | /* avoid division by zero */ | ||
73 | if (ch0 == 0) | ||
74 | return 0; | ||
75 | |||
76 | tmp = DIV_ROUND_UP(ch1 * 100, ch0); | ||
77 | if (tmp <= 52) { | ||
78 | lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0 | ||
79 | * apds9300_lux_ratio[tmp] * 5930ull, 1000); | ||
80 | } else if (tmp <= 65) { | ||
81 | lux = 2290 * ch0 - 2910 * ch1; | ||
82 | } else if (tmp <= 80) { | ||
83 | lux = 1570 * ch0 - 1800 * ch1; | ||
84 | } else if (tmp <= 130) { | ||
85 | lux = 338 * ch0 - 260 * ch1; | ||
86 | } else { | ||
87 | lux = 0; | ||
88 | } | ||
89 | |||
90 | return lux / 100000; | ||
91 | } | ||
92 | |||
93 | static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number) | ||
94 | { | ||
95 | int ret; | ||
96 | u8 flags = APDS9300_CMD | APDS9300_WORD; | ||
97 | |||
98 | if (!data->power_state) | ||
99 | return -EBUSY; | ||
100 | |||
101 | /* Select ADC0 or ADC1 data register */ | ||
102 | flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW; | ||
103 | |||
104 | ret = i2c_smbus_read_word_data(data->client, flags); | ||
105 | if (ret < 0) | ||
106 | dev_err(&data->client->dev, | ||
107 | "failed to read ADC%d value\n", adc_number); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int apds9300_set_thresh_low(struct apds9300_data *data, int value) | ||
113 | { | ||
114 | int ret; | ||
115 | |||
116 | if (!data->power_state) | ||
117 | return -EBUSY; | ||
118 | |||
119 | if (value > APDS9300_THRESH_MAX) | ||
120 | return -EINVAL; | ||
121 | |||
122 | ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW | ||
123 | | APDS9300_CMD | APDS9300_WORD, value); | ||
124 | if (ret) { | ||
125 | dev_err(&data->client->dev, "failed to set thresh_low\n"); | ||
126 | return ret; | ||
127 | } | ||
128 | data->thresh_low = value; | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int apds9300_set_thresh_hi(struct apds9300_data *data, int value) | ||
134 | { | ||
135 | int ret; | ||
136 | |||
137 | if (!data->power_state) | ||
138 | return -EBUSY; | ||
139 | |||
140 | if (value > APDS9300_THRESH_MAX) | ||
141 | return -EINVAL; | ||
142 | |||
143 | ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW | ||
144 | | APDS9300_CMD | APDS9300_WORD, value); | ||
145 | if (ret) { | ||
146 | dev_err(&data->client->dev, "failed to set thresh_hi\n"); | ||
147 | return ret; | ||
148 | } | ||
149 | data->thresh_hi = value; | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int apds9300_set_intr_state(struct apds9300_data *data, int state) | ||
155 | { | ||
156 | int ret; | ||
157 | u8 cmd; | ||
158 | |||
159 | if (!data->power_state) | ||
160 | return -EBUSY; | ||
161 | |||
162 | cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00; | ||
163 | ret = i2c_smbus_write_byte_data(data->client, | ||
164 | APDS9300_INTERRUPT | APDS9300_CMD, cmd); | ||
165 | if (ret) { | ||
166 | dev_err(&data->client->dev, | ||
167 | "failed to set interrupt state %d\n", state); | ||
168 | return ret; | ||
169 | } | ||
170 | data->intr_en = state; | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int apds9300_set_power_state(struct apds9300_data *data, int state) | ||
176 | { | ||
177 | int ret; | ||
178 | u8 cmd; | ||
179 | |||
180 | cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF; | ||
181 | ret = i2c_smbus_write_byte_data(data->client, | ||
182 | APDS9300_CONTROL | APDS9300_CMD, cmd); | ||
183 | if (ret) { | ||
184 | dev_err(&data->client->dev, | ||
185 | "failed to set power state %d\n", state); | ||
186 | return ret; | ||
187 | } | ||
188 | data->power_state = state; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static void apds9300_clear_intr(struct apds9300_data *data) | ||
194 | { | ||
195 | int ret; | ||
196 | |||
197 | ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD); | ||
198 | if (ret < 0) | ||
199 | dev_err(&data->client->dev, "failed to clear interrupt\n"); | ||
200 | } | ||
201 | |||
202 | static int apds9300_chip_init(struct apds9300_data *data) | ||
203 | { | ||
204 | int ret; | ||
205 | |||
206 | /* Need to set power off to ensure that the chip is off */ | ||
207 | ret = apds9300_set_power_state(data, 0); | ||
208 | if (ret < 0) | ||
209 | goto err; | ||
210 | /* | ||
211 | * Probe the chip. To do so we try to power up the device and then to | ||
212 | * read back the 0x03 code | ||
213 | */ | ||
214 | ret = apds9300_set_power_state(data, 1); | ||
215 | if (ret < 0) | ||
216 | goto err; | ||
217 | ret = i2c_smbus_read_byte_data(data->client, | ||
218 | APDS9300_CONTROL | APDS9300_CMD); | ||
219 | if (ret != APDS9300_POWER_ON) { | ||
220 | ret = -ENODEV; | ||
221 | goto err; | ||
222 | } | ||
223 | /* | ||
224 | * Disable interrupt to ensure thai it is doesn't enable | ||
225 | * i.e. after device soft reset | ||
226 | */ | ||
227 | ret = apds9300_set_intr_state(data, 0); | ||
228 | if (ret < 0) | ||
229 | goto err; | ||
230 | |||
231 | return 0; | ||
232 | |||
233 | err: | ||
234 | dev_err(&data->client->dev, "failed to init the chip\n"); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static int apds9300_read_raw(struct iio_dev *indio_dev, | ||
239 | struct iio_chan_spec const *chan, int *val, int *val2, | ||
240 | long mask) | ||
241 | { | ||
242 | int ch0, ch1, ret = -EINVAL; | ||
243 | struct apds9300_data *data = iio_priv(indio_dev); | ||
244 | |||
245 | mutex_lock(&data->mutex); | ||
246 | switch (chan->type) { | ||
247 | case IIO_LIGHT: | ||
248 | ch0 = apds9300_get_adc_val(data, 0); | ||
249 | if (ch0 < 0) { | ||
250 | ret = ch0; | ||
251 | break; | ||
252 | } | ||
253 | ch1 = apds9300_get_adc_val(data, 1); | ||
254 | if (ch1 < 0) { | ||
255 | ret = ch1; | ||
256 | break; | ||
257 | } | ||
258 | *val = apds9300_calculate_lux(ch0, ch1); | ||
259 | ret = IIO_VAL_INT; | ||
260 | break; | ||
261 | case IIO_INTENSITY: | ||
262 | ret = apds9300_get_adc_val(data, chan->channel); | ||
263 | if (ret < 0) | ||
264 | break; | ||
265 | *val = ret; | ||
266 | ret = IIO_VAL_INT; | ||
267 | break; | ||
268 | default: | ||
269 | break; | ||
270 | } | ||
271 | mutex_unlock(&data->mutex); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code, | ||
277 | int *val) | ||
278 | { | ||
279 | struct apds9300_data *data = iio_priv(indio_dev); | ||
280 | |||
281 | switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { | ||
282 | case IIO_EV_DIR_RISING: | ||
283 | *val = data->thresh_hi; | ||
284 | break; | ||
285 | case IIO_EV_DIR_FALLING: | ||
286 | *val = data->thresh_low; | ||
287 | break; | ||
288 | default: | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code, | ||
296 | int val) | ||
297 | { | ||
298 | struct apds9300_data *data = iio_priv(indio_dev); | ||
299 | int ret; | ||
300 | |||
301 | mutex_lock(&data->mutex); | ||
302 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING) | ||
303 | ret = apds9300_set_thresh_hi(data, val); | ||
304 | else | ||
305 | ret = apds9300_set_thresh_low(data, val); | ||
306 | mutex_unlock(&data->mutex); | ||
307 | |||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | static int apds9300_read_interrupt_config(struct iio_dev *indio_dev, | ||
312 | u64 event_code) | ||
313 | { | ||
314 | struct apds9300_data *data = iio_priv(indio_dev); | ||
315 | |||
316 | return data->intr_en; | ||
317 | } | ||
318 | |||
319 | static int apds9300_write_interrupt_config(struct iio_dev *indio_dev, | ||
320 | u64 event_code, int state) | ||
321 | { | ||
322 | struct apds9300_data *data = iio_priv(indio_dev); | ||
323 | int ret; | ||
324 | |||
325 | mutex_lock(&data->mutex); | ||
326 | ret = apds9300_set_intr_state(data, state); | ||
327 | mutex_unlock(&data->mutex); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static const struct iio_info apds9300_info_no_irq = { | ||
333 | .driver_module = THIS_MODULE, | ||
334 | .read_raw = apds9300_read_raw, | ||
335 | }; | ||
336 | |||
337 | static const struct iio_info apds9300_info = { | ||
338 | .driver_module = THIS_MODULE, | ||
339 | .read_raw = apds9300_read_raw, | ||
340 | .read_event_value = apds9300_read_thresh, | ||
341 | .write_event_value = apds9300_write_thresh, | ||
342 | .read_event_config = apds9300_read_interrupt_config, | ||
343 | .write_event_config = apds9300_write_interrupt_config, | ||
344 | }; | ||
345 | |||
346 | static const struct iio_chan_spec apds9300_channels[] = { | ||
347 | { | ||
348 | .type = IIO_LIGHT, | ||
349 | .channel = 0, | ||
350 | .indexed = true, | ||
351 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
352 | }, { | ||
353 | .type = IIO_INTENSITY, | ||
354 | .channel = 0, | ||
355 | .channel2 = IIO_MOD_LIGHT_BOTH, | ||
356 | .indexed = true, | ||
357 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
358 | .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH, | ||
359 | IIO_EV_DIR_RISING) | | ||
360 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, | ||
361 | IIO_EV_DIR_FALLING)), | ||
362 | }, { | ||
363 | .type = IIO_INTENSITY, | ||
364 | .channel = 1, | ||
365 | .channel2 = IIO_MOD_LIGHT_IR, | ||
366 | .indexed = true, | ||
367 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
368 | }, | ||
369 | }; | ||
370 | |||
371 | static irqreturn_t apds9300_interrupt_handler(int irq, void *private) | ||
372 | { | ||
373 | struct iio_dev *dev_info = private; | ||
374 | struct apds9300_data *data = iio_priv(dev_info); | ||
375 | |||
376 | iio_push_event(dev_info, | ||
377 | IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, | ||
378 | IIO_EV_TYPE_THRESH, | ||
379 | IIO_EV_DIR_EITHER), | ||
380 | iio_get_time_ns()); | ||
381 | |||
382 | apds9300_clear_intr(data); | ||
383 | |||
384 | return IRQ_HANDLED; | ||
385 | } | ||
386 | |||
387 | static int apds9300_probe(struct i2c_client *client, | ||
388 | const struct i2c_device_id *id) | ||
389 | { | ||
390 | struct apds9300_data *data; | ||
391 | struct iio_dev *indio_dev; | ||
392 | int ret; | ||
393 | |||
394 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
395 | if (!indio_dev) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | data = iio_priv(indio_dev); | ||
399 | i2c_set_clientdata(client, indio_dev); | ||
400 | data->client = client; | ||
401 | |||
402 | ret = apds9300_chip_init(data); | ||
403 | if (ret < 0) | ||
404 | goto err; | ||
405 | |||
406 | mutex_init(&data->mutex); | ||
407 | |||
408 | indio_dev->dev.parent = &client->dev; | ||
409 | indio_dev->channels = apds9300_channels; | ||
410 | indio_dev->num_channels = ARRAY_SIZE(apds9300_channels); | ||
411 | indio_dev->name = APDS9300_DRV_NAME; | ||
412 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
413 | |||
414 | if (client->irq) | ||
415 | indio_dev->info = &apds9300_info; | ||
416 | else | ||
417 | indio_dev->info = &apds9300_info_no_irq; | ||
418 | |||
419 | if (client->irq) { | ||
420 | ret = devm_request_threaded_irq(&client->dev, client->irq, | ||
421 | NULL, apds9300_interrupt_handler, | ||
422 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
423 | APDS9300_IRQ_NAME, indio_dev); | ||
424 | if (ret) { | ||
425 | dev_err(&client->dev, "irq request error %d\n", -ret); | ||
426 | goto err; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | ret = iio_device_register(indio_dev); | ||
431 | if (ret < 0) | ||
432 | goto err; | ||
433 | |||
434 | return 0; | ||
435 | |||
436 | err: | ||
437 | /* Ensure that power off in case of error */ | ||
438 | apds9300_set_power_state(data, 0); | ||
439 | return ret; | ||
440 | } | ||
441 | |||
442 | static int apds9300_remove(struct i2c_client *client) | ||
443 | { | ||
444 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
445 | struct apds9300_data *data = iio_priv(indio_dev); | ||
446 | |||
447 | iio_device_unregister(indio_dev); | ||
448 | |||
449 | /* Ensure that power off and interrupts are disabled */ | ||
450 | apds9300_set_intr_state(data, 0); | ||
451 | apds9300_set_power_state(data, 0); | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | #ifdef CONFIG_PM_SLEEP | ||
457 | static int apds9300_suspend(struct device *dev) | ||
458 | { | ||
459 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
460 | struct apds9300_data *data = iio_priv(indio_dev); | ||
461 | int ret; | ||
462 | |||
463 | mutex_lock(&data->mutex); | ||
464 | ret = apds9300_set_power_state(data, 0); | ||
465 | mutex_unlock(&data->mutex); | ||
466 | |||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | static int apds9300_resume(struct device *dev) | ||
471 | { | ||
472 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
473 | struct apds9300_data *data = iio_priv(indio_dev); | ||
474 | int ret; | ||
475 | |||
476 | mutex_lock(&data->mutex); | ||
477 | ret = apds9300_set_power_state(data, 1); | ||
478 | mutex_unlock(&data->mutex); | ||
479 | |||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume); | ||
484 | #define APDS9300_PM_OPS (&apds9300_pm_ops) | ||
485 | #else | ||
486 | #define APDS9300_PM_OPS NULL | ||
487 | #endif | ||
488 | |||
489 | static struct i2c_device_id apds9300_id[] = { | ||
490 | { APDS9300_DRV_NAME, 0 }, | ||
491 | { } | ||
492 | }; | ||
493 | |||
494 | MODULE_DEVICE_TABLE(i2c, apds9300_id); | ||
495 | |||
496 | static struct i2c_driver apds9300_driver = { | ||
497 | .driver = { | ||
498 | .name = APDS9300_DRV_NAME, | ||
499 | .owner = THIS_MODULE, | ||
500 | .pm = APDS9300_PM_OPS, | ||
501 | }, | ||
502 | .probe = apds9300_probe, | ||
503 | .remove = apds9300_remove, | ||
504 | .id_table = apds9300_id, | ||
505 | }; | ||
506 | |||
507 | module_i2c_driver(apds9300_driver); | ||
508 | |||
509 | MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>"); | ||
510 | MODULE_AUTHOR("GlobalLogic inc."); | ||
511 | MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver"); | ||
512 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index cdc2cad0f01b..e59d00c3139c 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c | |||
@@ -30,10 +30,6 @@ | |||
30 | #include <linux/iio/triggered_buffer.h> | 30 | #include <linux/iio/triggered_buffer.h> |
31 | #include "../common/hid-sensors/hid-sensor-trigger.h" | 31 | #include "../common/hid-sensors/hid-sensor-trigger.h" |
32 | 32 | ||
33 | /*Format: HID-SENSOR-usage_id_in_hex*/ | ||
34 | /*Usage ID from spec for Ambiant-Light: 0x200041*/ | ||
35 | #define DRIVER_NAME "HID-SENSOR-200041" | ||
36 | |||
37 | #define CHANNEL_SCAN_INDEX_ILLUM 0 | 33 | #define CHANNEL_SCAN_INDEX_ILLUM 0 |
38 | 34 | ||
39 | struct als_state { | 35 | struct als_state { |
@@ -158,18 +154,10 @@ static int als_write_raw(struct iio_dev *indio_dev, | |||
158 | return ret; | 154 | return ret; |
159 | } | 155 | } |
160 | 156 | ||
161 | static int als_write_raw_get_fmt(struct iio_dev *indio_dev, | ||
162 | struct iio_chan_spec const *chan, | ||
163 | long mask) | ||
164 | { | ||
165 | return IIO_VAL_INT_PLUS_MICRO; | ||
166 | } | ||
167 | |||
168 | static const struct iio_info als_info = { | 157 | static const struct iio_info als_info = { |
169 | .driver_module = THIS_MODULE, | 158 | .driver_module = THIS_MODULE, |
170 | .read_raw = &als_read_raw, | 159 | .read_raw = &als_read_raw, |
171 | .write_raw = &als_write_raw, | 160 | .write_raw = &als_write_raw, |
172 | .write_raw_get_fmt = &als_write_raw_get_fmt, | ||
173 | }; | 161 | }; |
174 | 162 | ||
175 | /* Function to push data to buffer */ | 163 | /* Function to push data to buffer */ |
@@ -253,11 +241,9 @@ static int hid_als_probe(struct platform_device *pdev) | |||
253 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | 241 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; |
254 | struct iio_chan_spec *channels; | 242 | struct iio_chan_spec *channels; |
255 | 243 | ||
256 | indio_dev = iio_device_alloc(sizeof(struct als_state)); | 244 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state)); |
257 | if (indio_dev == NULL) { | 245 | if (!indio_dev) |
258 | ret = -ENOMEM; | 246 | return -ENOMEM; |
259 | goto error_ret; | ||
260 | } | ||
261 | platform_set_drvdata(pdev, indio_dev); | 247 | platform_set_drvdata(pdev, indio_dev); |
262 | 248 | ||
263 | als_state = iio_priv(indio_dev); | 249 | als_state = iio_priv(indio_dev); |
@@ -268,14 +254,13 @@ static int hid_als_probe(struct platform_device *pdev) | |||
268 | &als_state->common_attributes); | 254 | &als_state->common_attributes); |
269 | if (ret) { | 255 | if (ret) { |
270 | dev_err(&pdev->dev, "failed to setup common attributes\n"); | 256 | dev_err(&pdev->dev, "failed to setup common attributes\n"); |
271 | goto error_free_dev; | 257 | return ret; |
272 | } | 258 | } |
273 | 259 | ||
274 | channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL); | 260 | channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL); |
275 | if (!channels) { | 261 | if (!channels) { |
276 | ret = -ENOMEM; | ||
277 | dev_err(&pdev->dev, "failed to duplicate channels\n"); | 262 | dev_err(&pdev->dev, "failed to duplicate channels\n"); |
278 | goto error_free_dev; | 263 | return -ENOMEM; |
279 | } | 264 | } |
280 | 265 | ||
281 | ret = als_parse_report(pdev, hsdev, channels, | 266 | ret = als_parse_report(pdev, hsdev, channels, |
@@ -333,9 +318,6 @@ error_unreg_buffer_funcs: | |||
333 | iio_triggered_buffer_cleanup(indio_dev); | 318 | iio_triggered_buffer_cleanup(indio_dev); |
334 | error_free_dev_mem: | 319 | error_free_dev_mem: |
335 | kfree(indio_dev->channels); | 320 | kfree(indio_dev->channels); |
336 | error_free_dev: | ||
337 | iio_device_free(indio_dev); | ||
338 | error_ret: | ||
339 | return ret; | 321 | return ret; |
340 | } | 322 | } |
341 | 323 | ||
@@ -350,14 +332,23 @@ static int hid_als_remove(struct platform_device *pdev) | |||
350 | hid_sensor_remove_trigger(indio_dev); | 332 | hid_sensor_remove_trigger(indio_dev); |
351 | iio_triggered_buffer_cleanup(indio_dev); | 333 | iio_triggered_buffer_cleanup(indio_dev); |
352 | kfree(indio_dev->channels); | 334 | kfree(indio_dev->channels); |
353 | iio_device_free(indio_dev); | ||
354 | 335 | ||
355 | return 0; | 336 | return 0; |
356 | } | 337 | } |
357 | 338 | ||
339 | static struct platform_device_id hid_als_ids[] = { | ||
340 | { | ||
341 | /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ | ||
342 | .name = "HID-SENSOR-200041", | ||
343 | }, | ||
344 | { /* sentinel */ } | ||
345 | }; | ||
346 | MODULE_DEVICE_TABLE(platform, hid_als_ids); | ||
347 | |||
358 | static struct platform_driver hid_als_platform_driver = { | 348 | static struct platform_driver hid_als_platform_driver = { |
349 | .id_table = hid_als_ids, | ||
359 | .driver = { | 350 | .driver = { |
360 | .name = DRIVER_NAME, | 351 | .name = KBUILD_MODNAME, |
361 | .owner = THIS_MODULE, | 352 | .owner = THIS_MODULE, |
362 | }, | 353 | }, |
363 | .probe = hid_als_probe, | 354 | .probe = hid_als_probe, |
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 5fa31a4ef82a..c1aadc6b865a 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c | |||
@@ -847,7 +847,7 @@ static int lm3533_als_probe(struct platform_device *pdev) | |||
847 | return -EINVAL; | 847 | return -EINVAL; |
848 | } | 848 | } |
849 | 849 | ||
850 | indio_dev = iio_device_alloc(sizeof(*als)); | 850 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als)); |
851 | if (!indio_dev) | 851 | if (!indio_dev) |
852 | return -ENOMEM; | 852 | return -ENOMEM; |
853 | 853 | ||
@@ -870,7 +870,7 @@ static int lm3533_als_probe(struct platform_device *pdev) | |||
870 | if (als->irq) { | 870 | if (als->irq) { |
871 | ret = lm3533_als_setup_irq(als, indio_dev); | 871 | ret = lm3533_als_setup_irq(als, indio_dev); |
872 | if (ret) | 872 | if (ret) |
873 | goto err_free_dev; | 873 | return ret; |
874 | } | 874 | } |
875 | 875 | ||
876 | ret = lm3533_als_setup(als, pdata); | 876 | ret = lm3533_als_setup(als, pdata); |
@@ -894,8 +894,6 @@ err_disable: | |||
894 | err_free_irq: | 894 | err_free_irq: |
895 | if (als->irq) | 895 | if (als->irq) |
896 | free_irq(als->irq, indio_dev); | 896 | free_irq(als->irq, indio_dev); |
897 | err_free_dev: | ||
898 | iio_device_free(indio_dev); | ||
899 | 897 | ||
900 | return ret; | 898 | return ret; |
901 | } | 899 | } |
@@ -910,7 +908,6 @@ static int lm3533_als_remove(struct platform_device *pdev) | |||
910 | lm3533_als_disable(als); | 908 | lm3533_als_disable(als); |
911 | if (als->irq) | 909 | if (als->irq) |
912 | free_irq(als->irq, indio_dev); | 910 | free_irq(als->irq, indio_dev); |
913 | iio_device_free(indio_dev); | ||
914 | 911 | ||
915 | return 0; | 912 | return 0; |
916 | } | 913 | } |
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 1f529f36f138..ebb962c5c323 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c | |||
@@ -702,7 +702,7 @@ static int tsl2563_probe(struct i2c_client *client, | |||
702 | int err = 0; | 702 | int err = 0; |
703 | u8 id = 0; | 703 | u8 id = 0; |
704 | 704 | ||
705 | indio_dev = iio_device_alloc(sizeof(*chip)); | 705 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); |
706 | if (!indio_dev) | 706 | if (!indio_dev) |
707 | return -ENOMEM; | 707 | return -ENOMEM; |
708 | 708 | ||
@@ -714,13 +714,13 @@ static int tsl2563_probe(struct i2c_client *client, | |||
714 | err = tsl2563_detect(chip); | 714 | err = tsl2563_detect(chip); |
715 | if (err) { | 715 | if (err) { |
716 | dev_err(&client->dev, "detect error %d\n", -err); | 716 | dev_err(&client->dev, "detect error %d\n", -err); |
717 | goto fail1; | 717 | return err; |
718 | } | 718 | } |
719 | 719 | ||
720 | err = tsl2563_read_id(chip, &id); | 720 | err = tsl2563_read_id(chip, &id); |
721 | if (err) { | 721 | if (err) { |
722 | dev_err(&client->dev, "read id error %d\n", -err); | 722 | dev_err(&client->dev, "read id error %d\n", -err); |
723 | goto fail1; | 723 | return err; |
724 | } | 724 | } |
725 | 725 | ||
726 | mutex_init(&chip->lock); | 726 | mutex_init(&chip->lock); |
@@ -751,7 +751,7 @@ static int tsl2563_probe(struct i2c_client *client, | |||
751 | indio_dev->info = &tsl2563_info_no_irq; | 751 | indio_dev->info = &tsl2563_info_no_irq; |
752 | 752 | ||
753 | if (client->irq) { | 753 | if (client->irq) { |
754 | err = request_threaded_irq(client->irq, | 754 | err = devm_request_threaded_irq(&client->dev, client->irq, |
755 | NULL, | 755 | NULL, |
756 | &tsl2563_event_handler, | 756 | &tsl2563_event_handler, |
757 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | 757 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
@@ -759,14 +759,14 @@ static int tsl2563_probe(struct i2c_client *client, | |||
759 | indio_dev); | 759 | indio_dev); |
760 | if (err) { | 760 | if (err) { |
761 | dev_err(&client->dev, "irq request error %d\n", -err); | 761 | dev_err(&client->dev, "irq request error %d\n", -err); |
762 | goto fail1; | 762 | return err; |
763 | } | 763 | } |
764 | } | 764 | } |
765 | 765 | ||
766 | err = tsl2563_configure(chip); | 766 | err = tsl2563_configure(chip); |
767 | if (err) { | 767 | if (err) { |
768 | dev_err(&client->dev, "configure error %d\n", -err); | 768 | dev_err(&client->dev, "configure error %d\n", -err); |
769 | goto fail2; | 769 | return err; |
770 | } | 770 | } |
771 | 771 | ||
772 | INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work); | 772 | INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work); |
@@ -777,19 +777,14 @@ static int tsl2563_probe(struct i2c_client *client, | |||
777 | err = iio_device_register(indio_dev); | 777 | err = iio_device_register(indio_dev); |
778 | if (err) { | 778 | if (err) { |
779 | dev_err(&client->dev, "iio registration error %d\n", -err); | 779 | dev_err(&client->dev, "iio registration error %d\n", -err); |
780 | goto fail3; | 780 | goto fail; |
781 | } | 781 | } |
782 | 782 | ||
783 | return 0; | 783 | return 0; |
784 | 784 | ||
785 | fail3: | 785 | fail: |
786 | cancel_delayed_work(&chip->poweroff_work); | 786 | cancel_delayed_work(&chip->poweroff_work); |
787 | flush_scheduled_work(); | 787 | flush_scheduled_work(); |
788 | fail2: | ||
789 | if (client->irq) | ||
790 | free_irq(client->irq, indio_dev); | ||
791 | fail1: | ||
792 | iio_device_free(indio_dev); | ||
793 | return err; | 788 | return err; |
794 | } | 789 | } |
795 | 790 | ||
@@ -807,10 +802,6 @@ static int tsl2563_remove(struct i2c_client *client) | |||
807 | chip->intr); | 802 | chip->intr); |
808 | flush_scheduled_work(); | 803 | flush_scheduled_work(); |
809 | tsl2563_set_power(chip, 0); | 804 | tsl2563_set_power(chip, 0); |
810 | if (client->irq) | ||
811 | free_irq(client->irq, indio_dev); | ||
812 | |||
813 | iio_device_free(indio_dev); | ||
814 | 805 | ||
815 | return 0; | 806 | return 0; |
816 | } | 807 | } |
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 1014943d949a..2bb304215b1d 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c | |||
@@ -157,7 +157,7 @@ static int vcnl4000_probe(struct i2c_client *client, | |||
157 | struct iio_dev *indio_dev; | 157 | struct iio_dev *indio_dev; |
158 | int ret; | 158 | int ret; |
159 | 159 | ||
160 | indio_dev = iio_device_alloc(sizeof(*data)); | 160 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); |
161 | if (!indio_dev) | 161 | if (!indio_dev) |
162 | return -ENOMEM; | 162 | return -ENOMEM; |
163 | 163 | ||
@@ -167,7 +167,7 @@ static int vcnl4000_probe(struct i2c_client *client, | |||
167 | 167 | ||
168 | ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV); | 168 | ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV); |
169 | if (ret < 0) | 169 | if (ret < 0) |
170 | goto error_free_dev; | 170 | return ret; |
171 | 171 | ||
172 | dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n", | 172 | dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n", |
173 | ret >> 4, ret & 0xf); | 173 | ret >> 4, ret & 0xf); |
@@ -181,22 +181,14 @@ static int vcnl4000_probe(struct i2c_client *client, | |||
181 | 181 | ||
182 | ret = iio_device_register(indio_dev); | 182 | ret = iio_device_register(indio_dev); |
183 | if (ret < 0) | 183 | if (ret < 0) |
184 | goto error_free_dev; | 184 | return ret; |
185 | 185 | ||
186 | return 0; | 186 | return 0; |
187 | |||
188 | error_free_dev: | ||
189 | iio_device_free(indio_dev); | ||
190 | return ret; | ||
191 | } | 187 | } |
192 | 188 | ||
193 | static int vcnl4000_remove(struct i2c_client *client) | 189 | static int vcnl4000_remove(struct i2c_client *client) |
194 | { | 190 | { |
195 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | 191 | iio_device_unregister(i2c_get_clientdata(client)); |
196 | |||
197 | iio_device_unregister(indio_dev); | ||
198 | iio_device_free(indio_dev); | ||
199 | |||
200 | return 0; | 192 | return 0; |
201 | } | 193 | } |
202 | 194 | ||