Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *  tsl2550.c - Linux kernel modules for ambient light sensor
  4 *
  5 *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
  6 *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
  7 */
  8
  9#include <linux/module.h>
 10#include <linux/slab.h>
 11#include <linux/i2c.h>
 12#include <linux/mutex.h>
 13
 14#define TSL2550_DRV_NAME	"tsl2550"
 15#define DRIVER_VERSION		"1.2"
 16
 17/*
 18 * Defines
 19 */
 20
 21#define TSL2550_POWER_DOWN		0x00
 22#define TSL2550_POWER_UP		0x03
 23#define TSL2550_STANDARD_RANGE		0x18
 24#define TSL2550_EXTENDED_RANGE		0x1d
 25#define TSL2550_READ_ADC0		0x43
 26#define TSL2550_READ_ADC1		0x83
 27
 28/*
 29 * Structs
 30 */
 31
 32struct tsl2550_data {
 33	struct i2c_client *client;
 34	struct mutex update_lock;
 35
 36	unsigned int power_state:1;
 37	unsigned int operating_mode:1;
 38};
 39
 40/*
 41 * Global data
 42 */
 43
 44static const u8 TSL2550_MODE_RANGE[2] = {
 45	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
 46};
 47
 48/*
 49 * Management functions
 50 */
 51
 52static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
 53{
 54	struct tsl2550_data *data = i2c_get_clientdata(client);
 55
 56	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
 57
 58	data->operating_mode = mode;
 59
 60	return ret;
 61}
 62
 63static int tsl2550_set_power_state(struct i2c_client *client, int state)
 64{
 65	struct tsl2550_data *data = i2c_get_clientdata(client);
 66	int ret;
 67
 68	if (state == 0)
 69		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
 70	else {
 71		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
 72
 73		/* On power up we should reset operating mode also... */
 74		tsl2550_set_operating_mode(client, data->operating_mode);
 75	}
 76
 77	data->power_state = state;
 78
 79	return ret;
 80}
 81
 82static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
 83{
 84	int ret;
 85
 86	ret = i2c_smbus_read_byte_data(client, cmd);
 87	if (ret < 0)
 88		return ret;
 89	if (!(ret & 0x80))
 90		return -EAGAIN;
 91	return ret & 0x7f;	/* remove the "valid" bit */
 92}
 93
 94/*
 95 * LUX calculation
 96 */
 97
 98#define	TSL2550_MAX_LUX		1846
 99
100static const u8 ratio_lut[] = {
101	100, 100, 100, 100, 100, 100, 100, 100,
102	100, 100, 100, 100, 100, 100, 99, 99,
103	99, 99, 99, 99, 99, 99, 99, 99,
104	99, 99, 99, 98, 98, 98, 98, 98,
105	98, 98, 97, 97, 97, 97, 97, 96,
106	96, 96, 96, 95, 95, 95, 94, 94,
107	93, 93, 93, 92, 92, 91, 91, 90,
108	89, 89, 88, 87, 87, 86, 85, 84,
109	83, 82, 81, 80, 79, 78, 77, 75,
110	74, 73, 71, 69, 68, 66, 64, 62,
111	60, 58, 56, 54, 52, 49, 47, 44,
112	42, 41, 40, 40, 39, 39, 38, 38,
113	37, 37, 37, 36, 36, 36, 35, 35,
114	35, 35, 34, 34, 34, 34, 33, 33,
115	33, 33, 32, 32, 32, 32, 32, 31,
116	31, 31, 31, 31, 30, 30, 30, 30,
117	30,
118};
119
120static const u16 count_lut[] = {
121	0, 1, 2, 3, 4, 5, 6, 7,
122	8, 9, 10, 11, 12, 13, 14, 15,
123	16, 18, 20, 22, 24, 26, 28, 30,
124	32, 34, 36, 38, 40, 42, 44, 46,
125	49, 53, 57, 61, 65, 69, 73, 77,
126	81, 85, 89, 93, 97, 101, 105, 109,
127	115, 123, 131, 139, 147, 155, 163, 171,
128	179, 187, 195, 203, 211, 219, 227, 235,
129	247, 263, 279, 295, 311, 327, 343, 359,
130	375, 391, 407, 423, 439, 455, 471, 487,
131	511, 543, 575, 607, 639, 671, 703, 735,
132	767, 799, 831, 863, 895, 927, 959, 991,
133	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
134	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
135	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
136	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
137};
138
139/*
140 * This function is described into Taos TSL2550 Designer's Notebook
141 * pages 2, 3.
142 */
143static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
144{
145	unsigned int lux;
146
147	/* Look up count from channel values */
148	u16 c0 = count_lut[ch0];
149	u16 c1 = count_lut[ch1];
150
151	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
152	if (c1 <= c0)
153		if (c0) {
154			/*
155			 * Calculate ratio.
156			 * Note: the "128" is a scaling factor
157			 */
158			u8 r = c1 * 128 / c0;
159
160			/* Calculate LUX */
161			lux = ((c0 - c1) * ratio_lut[r]) / 256;
162		} else
163			lux = 0;
164	else
165		return 0;
166
167	/* LUX range check */
168	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
169}
170
171/*
172 * SysFS support
173 */
174
175static ssize_t tsl2550_show_power_state(struct device *dev,
176		struct device_attribute *attr, char *buf)
177{
178	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
179
180	return sprintf(buf, "%u\n", data->power_state);
181}
182
183static ssize_t tsl2550_store_power_state(struct device *dev,
184		struct device_attribute *attr, const char *buf, size_t count)
185{
186	struct i2c_client *client = to_i2c_client(dev);
187	struct tsl2550_data *data = i2c_get_clientdata(client);
188	unsigned long val;
189	int ret;
190
191	if (kstrtoul(buf, 10, &val) || val > 1)
192		return -EINVAL;
193
194	mutex_lock(&data->update_lock);
195	ret = tsl2550_set_power_state(client, val);
196	mutex_unlock(&data->update_lock);
197
198	if (ret < 0)
199		return ret;
200
201	return count;
202}
203
204static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
205		   tsl2550_show_power_state, tsl2550_store_power_state);
206
207static ssize_t tsl2550_show_operating_mode(struct device *dev,
208		struct device_attribute *attr, char *buf)
209{
210	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
211
212	return sprintf(buf, "%u\n", data->operating_mode);
213}
214
215static ssize_t tsl2550_store_operating_mode(struct device *dev,
216		struct device_attribute *attr, const char *buf, size_t count)
217{
218	struct i2c_client *client = to_i2c_client(dev);
219	struct tsl2550_data *data = i2c_get_clientdata(client);
220	unsigned long val;
221	int ret;
222
223	if (kstrtoul(buf, 10, &val) || val > 1)
224		return -EINVAL;
225
226	if (data->power_state == 0)
227		return -EBUSY;
228
229	mutex_lock(&data->update_lock);
230	ret = tsl2550_set_operating_mode(client, val);
231	mutex_unlock(&data->update_lock);
232
233	if (ret < 0)
234		return ret;
235
236	return count;
237}
238
239static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
240		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
241
242static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
243{
244	struct tsl2550_data *data = i2c_get_clientdata(client);
245	u8 ch0, ch1;
246	int ret;
247
248	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
249	if (ret < 0)
250		return ret;
251	ch0 = ret;
252
253	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
254	if (ret < 0)
255		return ret;
256	ch1 = ret;
257
258	/* Do the job */
259	ret = tsl2550_calculate_lux(ch0, ch1);
260	if (ret < 0)
261		return ret;
262	if (data->operating_mode == 1)
263		ret *= 5;
264
265	return sprintf(buf, "%d\n", ret);
266}
267
268static ssize_t tsl2550_show_lux1_input(struct device *dev,
269			struct device_attribute *attr, char *buf)
270{
271	struct i2c_client *client = to_i2c_client(dev);
272	struct tsl2550_data *data = i2c_get_clientdata(client);
273	int ret;
274
275	/* No LUX data if not operational */
276	if (!data->power_state)
277		return -EBUSY;
278
279	mutex_lock(&data->update_lock);
280	ret = __tsl2550_show_lux(client, buf);
281	mutex_unlock(&data->update_lock);
282
283	return ret;
284}
285
286static DEVICE_ATTR(lux1_input, S_IRUGO,
287		   tsl2550_show_lux1_input, NULL);
288
289static struct attribute *tsl2550_attributes[] = {
290	&dev_attr_power_state.attr,
291	&dev_attr_operating_mode.attr,
292	&dev_attr_lux1_input.attr,
293	NULL
294};
295
296static const struct attribute_group tsl2550_attr_group = {
297	.attrs = tsl2550_attributes,
298};
299
300/*
301 * Initialization function
302 */
303
304static int tsl2550_init_client(struct i2c_client *client)
305{
306	struct tsl2550_data *data = i2c_get_clientdata(client);
307	int err;
308
309	/*
310	 * Probe the chip. To do so we try to power up the device and then to
311	 * read back the 0x03 code
312	 */
313	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
314	if (err < 0)
315		return err;
316	if (err != TSL2550_POWER_UP)
317		return -ENODEV;
318	data->power_state = 1;
319
320	/* Set the default operating mode */
321	err = i2c_smbus_write_byte(client,
322				   TSL2550_MODE_RANGE[data->operating_mode]);
323	if (err < 0)
324		return err;
325
326	return 0;
327}
328
329/*
330 * I2C init/probing/exit functions
331 */
332
333static struct i2c_driver tsl2550_driver;
334static int tsl2550_probe(struct i2c_client *client)
335{
336	struct i2c_adapter *adapter = client->adapter;
337	struct tsl2550_data *data;
338	int *opmode, err = 0;
339
340	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
341					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
342		err = -EIO;
343		goto exit;
344	}
345
346	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
347	if (!data) {
348		err = -ENOMEM;
349		goto exit;
350	}
351	data->client = client;
352	i2c_set_clientdata(client, data);
353
354	/* Check platform data */
355	opmode = client->dev.platform_data;
356	if (opmode) {
357		if (*opmode < 0 || *opmode > 1) {
358			dev_err(&client->dev, "invalid operating_mode (%d)\n",
359					*opmode);
360			err = -EINVAL;
361			goto exit_kfree;
362		}
363		data->operating_mode = *opmode;
364	} else
365		data->operating_mode = 0;	/* default mode is standard */
366	dev_info(&client->dev, "%s operating mode\n",
367			data->operating_mode ? "extended" : "standard");
368
369	mutex_init(&data->update_lock);
370
371	/* Initialize the TSL2550 chip */
372	err = tsl2550_init_client(client);
373	if (err)
374		goto exit_kfree;
375
376	/* Register sysfs hooks */
377	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
378	if (err)
379		goto exit_kfree;
380
381	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
382
383	return 0;
384
385exit_kfree:
386	kfree(data);
387exit:
388	return err;
389}
390
391static void tsl2550_remove(struct i2c_client *client)
392{
393	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
394
395	/* Power down the device */
396	tsl2550_set_power_state(client, 0);
397
398	kfree(i2c_get_clientdata(client));
399}
400
401#ifdef CONFIG_PM_SLEEP
402
403static int tsl2550_suspend(struct device *dev)
404{
405	return tsl2550_set_power_state(to_i2c_client(dev), 0);
406}
407
408static int tsl2550_resume(struct device *dev)
409{
410	return tsl2550_set_power_state(to_i2c_client(dev), 1);
411}
412
413static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
414#define TSL2550_PM_OPS (&tsl2550_pm_ops)
415
416#else
417
418#define TSL2550_PM_OPS NULL
419
420#endif /* CONFIG_PM_SLEEP */
421
422static const struct i2c_device_id tsl2550_id[] = {
423	{ "tsl2550" },
424	{ }
425};
426MODULE_DEVICE_TABLE(i2c, tsl2550_id);
427
428static const struct of_device_id tsl2550_of_match[] = {
429	{ .compatible = "taos,tsl2550" },
430	{ }
431};
432MODULE_DEVICE_TABLE(of, tsl2550_of_match);
433
434static struct i2c_driver tsl2550_driver = {
435	.driver = {
436		.name	= TSL2550_DRV_NAME,
437		.of_match_table = tsl2550_of_match,
438		.pm	= TSL2550_PM_OPS,
439	},
440	.probe = tsl2550_probe,
441	.remove	= tsl2550_remove,
442	.id_table = tsl2550_id,
443};
444
445module_i2c_driver(tsl2550_driver);
446
447MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
448MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
449MODULE_LICENSE("GPL");
450MODULE_VERSION(DRIVER_VERSION);
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *  tsl2550.c - Linux kernel modules for ambient light sensor
  4 *
  5 *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
  6 *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
  7 */
  8
  9#include <linux/module.h>
 10#include <linux/slab.h>
 11#include <linux/i2c.h>
 12#include <linux/mutex.h>
 13
 14#define TSL2550_DRV_NAME	"tsl2550"
 15#define DRIVER_VERSION		"1.2"
 16
 17/*
 18 * Defines
 19 */
 20
 21#define TSL2550_POWER_DOWN		0x00
 22#define TSL2550_POWER_UP		0x03
 23#define TSL2550_STANDARD_RANGE		0x18
 24#define TSL2550_EXTENDED_RANGE		0x1d
 25#define TSL2550_READ_ADC0		0x43
 26#define TSL2550_READ_ADC1		0x83
 27
 28/*
 29 * Structs
 30 */
 31
 32struct tsl2550_data {
 33	struct i2c_client *client;
 34	struct mutex update_lock;
 35
 36	unsigned int power_state:1;
 37	unsigned int operating_mode:1;
 38};
 39
 40/*
 41 * Global data
 42 */
 43
 44static const u8 TSL2550_MODE_RANGE[2] = {
 45	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
 46};
 47
 48/*
 49 * Management functions
 50 */
 51
 52static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
 53{
 54	struct tsl2550_data *data = i2c_get_clientdata(client);
 55
 56	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
 57
 58	data->operating_mode = mode;
 59
 60	return ret;
 61}
 62
 63static int tsl2550_set_power_state(struct i2c_client *client, int state)
 64{
 65	struct tsl2550_data *data = i2c_get_clientdata(client);
 66	int ret;
 67
 68	if (state == 0)
 69		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
 70	else {
 71		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
 72
 73		/* On power up we should reset operating mode also... */
 74		tsl2550_set_operating_mode(client, data->operating_mode);
 75	}
 76
 77	data->power_state = state;
 78
 79	return ret;
 80}
 81
 82static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
 83{
 84	int ret;
 85
 86	ret = i2c_smbus_read_byte_data(client, cmd);
 87	if (ret < 0)
 88		return ret;
 89	if (!(ret & 0x80))
 90		return -EAGAIN;
 91	return ret & 0x7f;	/* remove the "valid" bit */
 92}
 93
 94/*
 95 * LUX calculation
 96 */
 97
 98#define	TSL2550_MAX_LUX		1846
 99
100static const u8 ratio_lut[] = {
101	100, 100, 100, 100, 100, 100, 100, 100,
102	100, 100, 100, 100, 100, 100, 99, 99,
103	99, 99, 99, 99, 99, 99, 99, 99,
104	99, 99, 99, 98, 98, 98, 98, 98,
105	98, 98, 97, 97, 97, 97, 97, 96,
106	96, 96, 96, 95, 95, 95, 94, 94,
107	93, 93, 93, 92, 92, 91, 91, 90,
108	89, 89, 88, 87, 87, 86, 85, 84,
109	83, 82, 81, 80, 79, 78, 77, 75,
110	74, 73, 71, 69, 68, 66, 64, 62,
111	60, 58, 56, 54, 52, 49, 47, 44,
112	42, 41, 40, 40, 39, 39, 38, 38,
113	37, 37, 37, 36, 36, 36, 35, 35,
114	35, 35, 34, 34, 34, 34, 33, 33,
115	33, 33, 32, 32, 32, 32, 32, 31,
116	31, 31, 31, 31, 30, 30, 30, 30,
117	30,
118};
119
120static const u16 count_lut[] = {
121	0, 1, 2, 3, 4, 5, 6, 7,
122	8, 9, 10, 11, 12, 13, 14, 15,
123	16, 18, 20, 22, 24, 26, 28, 30,
124	32, 34, 36, 38, 40, 42, 44, 46,
125	49, 53, 57, 61, 65, 69, 73, 77,
126	81, 85, 89, 93, 97, 101, 105, 109,
127	115, 123, 131, 139, 147, 155, 163, 171,
128	179, 187, 195, 203, 211, 219, 227, 235,
129	247, 263, 279, 295, 311, 327, 343, 359,
130	375, 391, 407, 423, 439, 455, 471, 487,
131	511, 543, 575, 607, 639, 671, 703, 735,
132	767, 799, 831, 863, 895, 927, 959, 991,
133	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
134	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
135	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
136	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
137};
138
139/*
140 * This function is described into Taos TSL2550 Designer's Notebook
141 * pages 2, 3.
142 */
143static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
144{
145	unsigned int lux;
146
147	/* Look up count from channel values */
148	u16 c0 = count_lut[ch0];
149	u16 c1 = count_lut[ch1];
150
151	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
152	if (c1 <= c0)
153		if (c0) {
154			/*
155			 * Calculate ratio.
156			 * Note: the "128" is a scaling factor
157			 */
158			u8 r = c1 * 128 / c0;
159
160			/* Calculate LUX */
161			lux = ((c0 - c1) * ratio_lut[r]) / 256;
162		} else
163			lux = 0;
164	else
165		return 0;
166
167	/* LUX range check */
168	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
169}
170
171/*
172 * SysFS support
173 */
174
175static ssize_t tsl2550_show_power_state(struct device *dev,
176		struct device_attribute *attr, char *buf)
177{
178	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
179
180	return sprintf(buf, "%u\n", data->power_state);
181}
182
183static ssize_t tsl2550_store_power_state(struct device *dev,
184		struct device_attribute *attr, const char *buf, size_t count)
185{
186	struct i2c_client *client = to_i2c_client(dev);
187	struct tsl2550_data *data = i2c_get_clientdata(client);
188	unsigned long val = simple_strtoul(buf, NULL, 10);
189	int ret;
190
191	if (val > 1)
192		return -EINVAL;
193
194	mutex_lock(&data->update_lock);
195	ret = tsl2550_set_power_state(client, val);
196	mutex_unlock(&data->update_lock);
197
198	if (ret < 0)
199		return ret;
200
201	return count;
202}
203
204static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
205		   tsl2550_show_power_state, tsl2550_store_power_state);
206
207static ssize_t tsl2550_show_operating_mode(struct device *dev,
208		struct device_attribute *attr, char *buf)
209{
210	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
211
212	return sprintf(buf, "%u\n", data->operating_mode);
213}
214
215static ssize_t tsl2550_store_operating_mode(struct device *dev,
216		struct device_attribute *attr, const char *buf, size_t count)
217{
218	struct i2c_client *client = to_i2c_client(dev);
219	struct tsl2550_data *data = i2c_get_clientdata(client);
220	unsigned long val = simple_strtoul(buf, NULL, 10);
221	int ret;
222
223	if (val > 1)
224		return -EINVAL;
225
226	if (data->power_state == 0)
227		return -EBUSY;
228
229	mutex_lock(&data->update_lock);
230	ret = tsl2550_set_operating_mode(client, val);
231	mutex_unlock(&data->update_lock);
232
233	if (ret < 0)
234		return ret;
235
236	return count;
237}
238
239static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
240		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
241
242static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
243{
244	struct tsl2550_data *data = i2c_get_clientdata(client);
245	u8 ch0, ch1;
246	int ret;
247
248	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
249	if (ret < 0)
250		return ret;
251	ch0 = ret;
252
253	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
254	if (ret < 0)
255		return ret;
256	ch1 = ret;
257
258	/* Do the job */
259	ret = tsl2550_calculate_lux(ch0, ch1);
260	if (ret < 0)
261		return ret;
262	if (data->operating_mode == 1)
263		ret *= 5;
264
265	return sprintf(buf, "%d\n", ret);
266}
267
268static ssize_t tsl2550_show_lux1_input(struct device *dev,
269			struct device_attribute *attr, char *buf)
270{
271	struct i2c_client *client = to_i2c_client(dev);
272	struct tsl2550_data *data = i2c_get_clientdata(client);
273	int ret;
274
275	/* No LUX data if not operational */
276	if (!data->power_state)
277		return -EBUSY;
278
279	mutex_lock(&data->update_lock);
280	ret = __tsl2550_show_lux(client, buf);
281	mutex_unlock(&data->update_lock);
282
283	return ret;
284}
285
286static DEVICE_ATTR(lux1_input, S_IRUGO,
287		   tsl2550_show_lux1_input, NULL);
288
289static struct attribute *tsl2550_attributes[] = {
290	&dev_attr_power_state.attr,
291	&dev_attr_operating_mode.attr,
292	&dev_attr_lux1_input.attr,
293	NULL
294};
295
296static const struct attribute_group tsl2550_attr_group = {
297	.attrs = tsl2550_attributes,
298};
299
300/*
301 * Initialization function
302 */
303
304static int tsl2550_init_client(struct i2c_client *client)
305{
306	struct tsl2550_data *data = i2c_get_clientdata(client);
307	int err;
308
309	/*
310	 * Probe the chip. To do so we try to power up the device and then to
311	 * read back the 0x03 code
312	 */
313	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
314	if (err < 0)
315		return err;
316	if (err != TSL2550_POWER_UP)
317		return -ENODEV;
318	data->power_state = 1;
319
320	/* Set the default operating mode */
321	err = i2c_smbus_write_byte(client,
322				   TSL2550_MODE_RANGE[data->operating_mode]);
323	if (err < 0)
324		return err;
325
326	return 0;
327}
328
329/*
330 * I2C init/probing/exit functions
331 */
332
333static struct i2c_driver tsl2550_driver;
334static int tsl2550_probe(struct i2c_client *client)
335{
336	struct i2c_adapter *adapter = client->adapter;
337	struct tsl2550_data *data;
338	int *opmode, err = 0;
339
340	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
341					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
342		err = -EIO;
343		goto exit;
344	}
345
346	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
347	if (!data) {
348		err = -ENOMEM;
349		goto exit;
350	}
351	data->client = client;
352	i2c_set_clientdata(client, data);
353
354	/* Check platform data */
355	opmode = client->dev.platform_data;
356	if (opmode) {
357		if (*opmode < 0 || *opmode > 1) {
358			dev_err(&client->dev, "invalid operating_mode (%d)\n",
359					*opmode);
360			err = -EINVAL;
361			goto exit_kfree;
362		}
363		data->operating_mode = *opmode;
364	} else
365		data->operating_mode = 0;	/* default mode is standard */
366	dev_info(&client->dev, "%s operating mode\n",
367			data->operating_mode ? "extended" : "standard");
368
369	mutex_init(&data->update_lock);
370
371	/* Initialize the TSL2550 chip */
372	err = tsl2550_init_client(client);
373	if (err)
374		goto exit_kfree;
375
376	/* Register sysfs hooks */
377	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
378	if (err)
379		goto exit_kfree;
380
381	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
382
383	return 0;
384
385exit_kfree:
386	kfree(data);
387exit:
388	return err;
389}
390
391static void tsl2550_remove(struct i2c_client *client)
392{
393	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
394
395	/* Power down the device */
396	tsl2550_set_power_state(client, 0);
397
398	kfree(i2c_get_clientdata(client));
399}
400
401#ifdef CONFIG_PM_SLEEP
402
403static int tsl2550_suspend(struct device *dev)
404{
405	return tsl2550_set_power_state(to_i2c_client(dev), 0);
406}
407
408static int tsl2550_resume(struct device *dev)
409{
410	return tsl2550_set_power_state(to_i2c_client(dev), 1);
411}
412
413static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
414#define TSL2550_PM_OPS (&tsl2550_pm_ops)
415
416#else
417
418#define TSL2550_PM_OPS NULL
419
420#endif /* CONFIG_PM_SLEEP */
421
422static const struct i2c_device_id tsl2550_id[] = {
423	{ "tsl2550", 0 },
424	{ }
425};
426MODULE_DEVICE_TABLE(i2c, tsl2550_id);
427
428static const struct of_device_id tsl2550_of_match[] = {
429	{ .compatible = "taos,tsl2550" },
430	{ }
431};
432MODULE_DEVICE_TABLE(of, tsl2550_of_match);
433
434static struct i2c_driver tsl2550_driver = {
435	.driver = {
436		.name	= TSL2550_DRV_NAME,
437		.of_match_table = tsl2550_of_match,
438		.pm	= TSL2550_PM_OPS,
439	},
440	.probe = tsl2550_probe,
441	.remove	= tsl2550_remove,
442	.id_table = tsl2550_id,
443};
444
445module_i2c_driver(tsl2550_driver);
446
447MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
448MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
449MODULE_LICENSE("GPL");
450MODULE_VERSION(DRIVER_VERSION);