3 * ROHM Ambient Light Sensor Driver
5 * Copyright (C) 2010 Texas Instruments
6 * Author: Hemanth V <hemanthv@ti.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/i2c.h>
21 #include <linux/slab.h>
22 #include <linux/mutex.h>
23 #include <linux/platform_device.h>
24 #include <linux/delay.h>
26 #define BH1780_REG_CONTROL 0x80
27 #define BH1780_REG_PARTID 0x8A
28 #define BH1780_REG_MANFID 0x8B
29 #define BH1780_REG_DLOW 0x8C
30 #define BH1780_REG_DHIGH 0x8D
32 #define BH1780_REVMASK (0xf)
33 #define BH1780_POWMASK (0x3)
34 #define BH1780_POFF (0x0)
35 #define BH1780_PON (0x3)
37 /* power on settling time in ms */
38 #define BH1780_PON_DELAY 2
41 struct i2c_client
*client
;
43 /* lock for sysfs operations */
47 static int bh1780_write(struct bh1780_data
*ddata
, u8 reg
, u8 val
, char *msg
)
49 int ret
= i2c_smbus_write_byte_data(ddata
->client
, reg
, val
);
51 dev_err(&ddata
->client
->dev
,
52 "i2c_smbus_write_byte_data failed error %d Register (%s)\n",
57 static int bh1780_read(struct bh1780_data
*ddata
, u8 reg
, char *msg
)
59 int ret
= i2c_smbus_read_byte_data(ddata
->client
, reg
);
61 dev_err(&ddata
->client
->dev
,
62 "i2c_smbus_read_byte_data failed error %d Register (%s)\n",
67 static ssize_t
bh1780_show_lux(struct device
*dev
,
68 struct device_attribute
*attr
, char *buf
)
70 struct platform_device
*pdev
= to_platform_device(dev
);
71 struct bh1780_data
*ddata
= platform_get_drvdata(pdev
);
74 lsb
= bh1780_read(ddata
, BH1780_REG_DLOW
, "DLOW");
78 msb
= bh1780_read(ddata
, BH1780_REG_DHIGH
, "DHIGH");
82 return sprintf(buf
, "%d\n", (msb
<< 8) | lsb
);
85 static ssize_t
bh1780_show_power_state(struct device
*dev
,
86 struct device_attribute
*attr
,
89 struct platform_device
*pdev
= to_platform_device(dev
);
90 struct bh1780_data
*ddata
= platform_get_drvdata(pdev
);
93 state
= bh1780_read(ddata
, BH1780_REG_CONTROL
, "CONTROL");
97 return sprintf(buf
, "%d\n", state
& BH1780_POWMASK
);
100 static ssize_t
bh1780_store_power_state(struct device
*dev
,
101 struct device_attribute
*attr
,
102 const char *buf
, size_t count
)
104 struct platform_device
*pdev
= to_platform_device(dev
);
105 struct bh1780_data
*ddata
= platform_get_drvdata(pdev
);
109 error
= strict_strtoul(buf
, 0, &val
);
113 if (val
< BH1780_POFF
|| val
> BH1780_PON
)
116 mutex_lock(&ddata
->lock
);
118 error
= bh1780_write(ddata
, BH1780_REG_CONTROL
, val
, "CONTROL");
120 mutex_unlock(&ddata
->lock
);
124 msleep(BH1780_PON_DELAY
);
125 ddata
->power_state
= val
;
126 mutex_unlock(&ddata
->lock
);
131 static DEVICE_ATTR(lux
, S_IRUGO
, bh1780_show_lux
, NULL
);
133 static DEVICE_ATTR(power_state
, S_IWUSR
| S_IRUGO
,
134 bh1780_show_power_state
, bh1780_store_power_state
);
136 static struct attribute
*bh1780_attributes
[] = {
137 &dev_attr_power_state
.attr
,
142 static const struct attribute_group bh1780_attr_group
= {
143 .attrs
= bh1780_attributes
,
146 static int __devinit
bh1780_probe(struct i2c_client
*client
,
147 const struct i2c_device_id
*id
)
150 struct bh1780_data
*ddata
= NULL
;
151 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
153 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE
)) {
158 ddata
= kzalloc(sizeof(struct bh1780_data
), GFP_KERNEL
);
164 ddata
->client
= client
;
165 i2c_set_clientdata(client
, ddata
);
167 ret
= bh1780_read(ddata
, BH1780_REG_PARTID
, "PART ID");
171 dev_info(&client
->dev
, "Ambient Light Sensor, Rev : %d\n",
172 (ret
& BH1780_REVMASK
));
174 mutex_init(&ddata
->lock
);
176 ret
= sysfs_create_group(&client
->dev
.kobj
, &bh1780_attr_group
);
187 static int __devexit
bh1780_remove(struct i2c_client
*client
)
189 struct bh1780_data
*ddata
;
191 ddata
= i2c_get_clientdata(client
);
192 sysfs_remove_group(&client
->dev
.kobj
, &bh1780_attr_group
);
199 static int bh1780_suspend(struct device
*dev
)
201 struct bh1780_data
*ddata
;
203 struct i2c_client
*client
= to_i2c_client(dev
);
205 ddata
= i2c_get_clientdata(client
);
206 state
= bh1780_read(ddata
, BH1780_REG_CONTROL
, "CONTROL");
210 ddata
->power_state
= state
& BH1780_POWMASK
;
212 ret
= bh1780_write(ddata
, BH1780_REG_CONTROL
, BH1780_POFF
,
221 static int bh1780_resume(struct device
*dev
)
223 struct bh1780_data
*ddata
;
225 struct i2c_client
*client
= to_i2c_client(dev
);
227 ddata
= i2c_get_clientdata(client
);
228 state
= ddata
->power_state
;
229 ret
= bh1780_write(ddata
, BH1780_REG_CONTROL
, state
,
237 static SIMPLE_DEV_PM_OPS(bh1780_pm
, bh1780_suspend
, bh1780_resume
);
238 #define BH1780_PMOPS (&bh1780_pm)
240 #define BH1780_PMOPS NULL
241 #endif /* CONFIG_PM */
243 static const struct i2c_device_id bh1780_id
[] = {
248 static struct i2c_driver bh1780_driver
= {
249 .probe
= bh1780_probe
,
250 .remove
= bh1780_remove
,
251 .id_table
= bh1780_id
,
258 static int __init
bh1780_init(void)
260 return i2c_add_driver(&bh1780_driver
);
263 static void __exit
bh1780_exit(void)
265 i2c_del_driver(&bh1780_driver
);
268 module_init(bh1780_init
)
269 module_exit(bh1780_exit
)
271 MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver");
272 MODULE_LICENSE("GPL");
273 MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");