Linux Audio

Check our new training course

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