1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * ROHM 1780GLI Ambient Light Sensor Driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2016 Linaro Ltd.
6*4882a593Smuzhiyun * Author: Linus Walleij <linus.walleij@linaro.org>
7*4882a593Smuzhiyun * Loosely based on the previous BH1780 ALS misc driver
8*4882a593Smuzhiyun * Copyright (C) 2010 Texas Instruments
9*4882a593Smuzhiyun * Author: Hemanth V <hemanthv@ti.com>
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun #include <linux/i2c.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/platform_device.h>
14*4882a593Smuzhiyun #include <linux/delay.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
17*4882a593Smuzhiyun #include <linux/pm_runtime.h>
18*4882a593Smuzhiyun #include <linux/iio/iio.h>
19*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
20*4882a593Smuzhiyun #include <linux/bitops.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #define BH1780_CMD_BIT BIT(7)
23*4882a593Smuzhiyun #define BH1780_REG_CONTROL 0x00
24*4882a593Smuzhiyun #define BH1780_REG_PARTID 0x0A
25*4882a593Smuzhiyun #define BH1780_REG_MANFID 0x0B
26*4882a593Smuzhiyun #define BH1780_REG_DLOW 0x0C
27*4882a593Smuzhiyun #define BH1780_REG_DHIGH 0x0D
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define BH1780_REVMASK GENMASK(3,0)
30*4882a593Smuzhiyun #define BH1780_POWMASK GENMASK(1,0)
31*4882a593Smuzhiyun #define BH1780_POFF (0x0)
32*4882a593Smuzhiyun #define BH1780_PON (0x3)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* power on settling time in ms */
35*4882a593Smuzhiyun #define BH1780_PON_DELAY 2
36*4882a593Smuzhiyun /* max time before value available in ms */
37*4882a593Smuzhiyun #define BH1780_INTERVAL 250
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun struct bh1780_data {
40*4882a593Smuzhiyun struct i2c_client *client;
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun
bh1780_write(struct bh1780_data * bh1780,u8 reg,u8 val)43*4882a593Smuzhiyun static int bh1780_write(struct bh1780_data *bh1780, u8 reg, u8 val)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun int ret = i2c_smbus_write_byte_data(bh1780->client,
46*4882a593Smuzhiyun BH1780_CMD_BIT | reg,
47*4882a593Smuzhiyun val);
48*4882a593Smuzhiyun if (ret < 0)
49*4882a593Smuzhiyun dev_err(&bh1780->client->dev,
50*4882a593Smuzhiyun "i2c_smbus_write_byte_data failed error "
51*4882a593Smuzhiyun "%d, register %01x\n",
52*4882a593Smuzhiyun ret, reg);
53*4882a593Smuzhiyun return ret;
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
bh1780_read(struct bh1780_data * bh1780,u8 reg)56*4882a593Smuzhiyun static int bh1780_read(struct bh1780_data *bh1780, u8 reg)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun int ret = i2c_smbus_read_byte_data(bh1780->client,
59*4882a593Smuzhiyun BH1780_CMD_BIT | reg);
60*4882a593Smuzhiyun if (ret < 0)
61*4882a593Smuzhiyun dev_err(&bh1780->client->dev,
62*4882a593Smuzhiyun "i2c_smbus_read_byte_data failed error "
63*4882a593Smuzhiyun "%d, register %01x\n",
64*4882a593Smuzhiyun ret, reg);
65*4882a593Smuzhiyun return ret;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
bh1780_read_word(struct bh1780_data * bh1780,u8 reg)68*4882a593Smuzhiyun static int bh1780_read_word(struct bh1780_data *bh1780, u8 reg)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun int ret = i2c_smbus_read_word_data(bh1780->client,
71*4882a593Smuzhiyun BH1780_CMD_BIT | reg);
72*4882a593Smuzhiyun if (ret < 0)
73*4882a593Smuzhiyun dev_err(&bh1780->client->dev,
74*4882a593Smuzhiyun "i2c_smbus_read_word_data failed error "
75*4882a593Smuzhiyun "%d, register %01x\n",
76*4882a593Smuzhiyun ret, reg);
77*4882a593Smuzhiyun return ret;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
bh1780_debugfs_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)80*4882a593Smuzhiyun static int bh1780_debugfs_reg_access(struct iio_dev *indio_dev,
81*4882a593Smuzhiyun unsigned int reg, unsigned int writeval,
82*4882a593Smuzhiyun unsigned int *readval)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun struct bh1780_data *bh1780 = iio_priv(indio_dev);
85*4882a593Smuzhiyun int ret;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (!readval)
88*4882a593Smuzhiyun return bh1780_write(bh1780, (u8)reg, (u8)writeval);
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun ret = bh1780_read(bh1780, (u8)reg);
91*4882a593Smuzhiyun if (ret < 0)
92*4882a593Smuzhiyun return ret;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun *readval = ret;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun return 0;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
bh1780_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)99*4882a593Smuzhiyun static int bh1780_read_raw(struct iio_dev *indio_dev,
100*4882a593Smuzhiyun struct iio_chan_spec const *chan,
101*4882a593Smuzhiyun int *val, int *val2, long mask)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun struct bh1780_data *bh1780 = iio_priv(indio_dev);
104*4882a593Smuzhiyun int value;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun switch (mask) {
107*4882a593Smuzhiyun case IIO_CHAN_INFO_RAW:
108*4882a593Smuzhiyun switch (chan->type) {
109*4882a593Smuzhiyun case IIO_LIGHT:
110*4882a593Smuzhiyun pm_runtime_get_sync(&bh1780->client->dev);
111*4882a593Smuzhiyun value = bh1780_read_word(bh1780, BH1780_REG_DLOW);
112*4882a593Smuzhiyun if (value < 0)
113*4882a593Smuzhiyun return value;
114*4882a593Smuzhiyun pm_runtime_mark_last_busy(&bh1780->client->dev);
115*4882a593Smuzhiyun pm_runtime_put_autosuspend(&bh1780->client->dev);
116*4882a593Smuzhiyun *val = value;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun return IIO_VAL_INT;
119*4882a593Smuzhiyun default:
120*4882a593Smuzhiyun return -EINVAL;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun case IIO_CHAN_INFO_INT_TIME:
123*4882a593Smuzhiyun *val = 0;
124*4882a593Smuzhiyun *val2 = BH1780_INTERVAL * 1000;
125*4882a593Smuzhiyun return IIO_VAL_INT_PLUS_MICRO;
126*4882a593Smuzhiyun default:
127*4882a593Smuzhiyun return -EINVAL;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun static const struct iio_info bh1780_info = {
132*4882a593Smuzhiyun .read_raw = bh1780_read_raw,
133*4882a593Smuzhiyun .debugfs_reg_access = bh1780_debugfs_reg_access,
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun static const struct iio_chan_spec bh1780_channels[] = {
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun .type = IIO_LIGHT,
139*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
140*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_INT_TIME)
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun };
143*4882a593Smuzhiyun
bh1780_probe(struct i2c_client * client,const struct i2c_device_id * id)144*4882a593Smuzhiyun static int bh1780_probe(struct i2c_client *client,
145*4882a593Smuzhiyun const struct i2c_device_id *id)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun int ret;
148*4882a593Smuzhiyun struct bh1780_data *bh1780;
149*4882a593Smuzhiyun struct i2c_adapter *adapter = client->adapter;
150*4882a593Smuzhiyun struct iio_dev *indio_dev;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
153*4882a593Smuzhiyun return -EIO;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*bh1780));
156*4882a593Smuzhiyun if (!indio_dev)
157*4882a593Smuzhiyun return -ENOMEM;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun bh1780 = iio_priv(indio_dev);
160*4882a593Smuzhiyun bh1780->client = client;
161*4882a593Smuzhiyun i2c_set_clientdata(client, indio_dev);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun /* Power up the device */
164*4882a593Smuzhiyun ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON);
165*4882a593Smuzhiyun if (ret < 0)
166*4882a593Smuzhiyun return ret;
167*4882a593Smuzhiyun msleep(BH1780_PON_DELAY);
168*4882a593Smuzhiyun pm_runtime_get_noresume(&client->dev);
169*4882a593Smuzhiyun pm_runtime_set_active(&client->dev);
170*4882a593Smuzhiyun pm_runtime_enable(&client->dev);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun ret = bh1780_read(bh1780, BH1780_REG_PARTID);
173*4882a593Smuzhiyun if (ret < 0)
174*4882a593Smuzhiyun goto out_disable_pm;
175*4882a593Smuzhiyun dev_info(&client->dev,
176*4882a593Smuzhiyun "Ambient Light Sensor, Rev : %lu\n",
177*4882a593Smuzhiyun (ret & BH1780_REVMASK));
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /*
180*4882a593Smuzhiyun * As the device takes 250 ms to even come up with a fresh
181*4882a593Smuzhiyun * measurement after power-on, do not shut it down unnecessarily.
182*4882a593Smuzhiyun * Set autosuspend to a five seconds.
183*4882a593Smuzhiyun */
184*4882a593Smuzhiyun pm_runtime_set_autosuspend_delay(&client->dev, 5000);
185*4882a593Smuzhiyun pm_runtime_use_autosuspend(&client->dev);
186*4882a593Smuzhiyun pm_runtime_put(&client->dev);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun indio_dev->info = &bh1780_info;
189*4882a593Smuzhiyun indio_dev->name = "bh1780";
190*4882a593Smuzhiyun indio_dev->channels = bh1780_channels;
191*4882a593Smuzhiyun indio_dev->num_channels = ARRAY_SIZE(bh1780_channels);
192*4882a593Smuzhiyun indio_dev->modes = INDIO_DIRECT_MODE;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun ret = iio_device_register(indio_dev);
195*4882a593Smuzhiyun if (ret)
196*4882a593Smuzhiyun goto out_disable_pm;
197*4882a593Smuzhiyun return 0;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun out_disable_pm:
200*4882a593Smuzhiyun pm_runtime_put_noidle(&client->dev);
201*4882a593Smuzhiyun pm_runtime_disable(&client->dev);
202*4882a593Smuzhiyun return ret;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
bh1780_remove(struct i2c_client * client)205*4882a593Smuzhiyun static int bh1780_remove(struct i2c_client *client)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun struct iio_dev *indio_dev = i2c_get_clientdata(client);
208*4882a593Smuzhiyun struct bh1780_data *bh1780 = iio_priv(indio_dev);
209*4882a593Smuzhiyun int ret;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun iio_device_unregister(indio_dev);
212*4882a593Smuzhiyun pm_runtime_get_sync(&client->dev);
213*4882a593Smuzhiyun pm_runtime_put_noidle(&client->dev);
214*4882a593Smuzhiyun pm_runtime_disable(&client->dev);
215*4882a593Smuzhiyun ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF);
216*4882a593Smuzhiyun if (ret < 0) {
217*4882a593Smuzhiyun dev_err(&client->dev, "failed to power off\n");
218*4882a593Smuzhiyun return ret;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun return 0;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun #ifdef CONFIG_PM
bh1780_runtime_suspend(struct device * dev)225*4882a593Smuzhiyun static int bh1780_runtime_suspend(struct device *dev)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
228*4882a593Smuzhiyun struct iio_dev *indio_dev = i2c_get_clientdata(client);
229*4882a593Smuzhiyun struct bh1780_data *bh1780 = iio_priv(indio_dev);
230*4882a593Smuzhiyun int ret;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF);
233*4882a593Smuzhiyun if (ret < 0) {
234*4882a593Smuzhiyun dev_err(dev, "failed to runtime suspend\n");
235*4882a593Smuzhiyun return ret;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun return 0;
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
bh1780_runtime_resume(struct device * dev)241*4882a593Smuzhiyun static int bh1780_runtime_resume(struct device *dev)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
244*4882a593Smuzhiyun struct iio_dev *indio_dev = i2c_get_clientdata(client);
245*4882a593Smuzhiyun struct bh1780_data *bh1780 = iio_priv(indio_dev);
246*4882a593Smuzhiyun int ret;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON);
249*4882a593Smuzhiyun if (ret < 0) {
250*4882a593Smuzhiyun dev_err(dev, "failed to runtime resume\n");
251*4882a593Smuzhiyun return ret;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun /* Wait for power on, then for a value to be available */
255*4882a593Smuzhiyun msleep(BH1780_PON_DELAY + BH1780_INTERVAL);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun #endif /* CONFIG_PM */
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun static const struct dev_pm_ops bh1780_dev_pm_ops = {
262*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
263*4882a593Smuzhiyun pm_runtime_force_resume)
264*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(bh1780_runtime_suspend,
265*4882a593Smuzhiyun bh1780_runtime_resume, NULL)
266*4882a593Smuzhiyun };
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun static const struct i2c_device_id bh1780_id[] = {
269*4882a593Smuzhiyun { "bh1780", 0 },
270*4882a593Smuzhiyun { },
271*4882a593Smuzhiyun };
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, bh1780_id);
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun static const struct of_device_id of_bh1780_match[] = {
276*4882a593Smuzhiyun { .compatible = "rohm,bh1780gli", },
277*4882a593Smuzhiyun {},
278*4882a593Smuzhiyun };
279*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, of_bh1780_match);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun static struct i2c_driver bh1780_driver = {
282*4882a593Smuzhiyun .probe = bh1780_probe,
283*4882a593Smuzhiyun .remove = bh1780_remove,
284*4882a593Smuzhiyun .id_table = bh1780_id,
285*4882a593Smuzhiyun .driver = {
286*4882a593Smuzhiyun .name = "bh1780",
287*4882a593Smuzhiyun .pm = &bh1780_dev_pm_ops,
288*4882a593Smuzhiyun .of_match_table = of_bh1780_match,
289*4882a593Smuzhiyun },
290*4882a593Smuzhiyun };
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun module_i2c_driver(bh1780_driver);
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun MODULE_DESCRIPTION("ROHM BH1780GLI Ambient Light Sensor Driver");
295*4882a593Smuzhiyun MODULE_LICENSE("GPL");
296*4882a593Smuzhiyun MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
297