18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * ROHM BH1710/BH1715/BH1721/BH1750/BH1751 ambient light sensor driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Data sheets:
88c2ecf20Sopenharmony_ci *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1710fvc-e.pdf
98c2ecf20Sopenharmony_ci *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1715fvc-e.pdf
108c2ecf20Sopenharmony_ci *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf
118c2ecf20Sopenharmony_ci *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
128c2ecf20Sopenharmony_ci *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1751fvi-e.pdf
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * 7-bit I2C slave addresses:
158c2ecf20Sopenharmony_ci *  0x23 (ADDR pin low)
168c2ecf20Sopenharmony_ci *  0x5C (ADDR pin high)
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <linux/delay.h>
218c2ecf20Sopenharmony_ci#include <linux/i2c.h>
228c2ecf20Sopenharmony_ci#include <linux/iio/iio.h>
238c2ecf20Sopenharmony_ci#include <linux/iio/sysfs.h>
248c2ecf20Sopenharmony_ci#include <linux/module.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define BH1750_POWER_DOWN		0x00
278c2ecf20Sopenharmony_ci#define BH1750_ONE_TIME_H_RES_MODE	0x20 /* auto-mode for BH1721 */
288c2ecf20Sopenharmony_ci#define BH1750_CHANGE_INT_TIME_H_BIT	0x40
298c2ecf20Sopenharmony_ci#define BH1750_CHANGE_INT_TIME_L_BIT	0x60
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cienum {
328c2ecf20Sopenharmony_ci	BH1710,
338c2ecf20Sopenharmony_ci	BH1721,
348c2ecf20Sopenharmony_ci	BH1750,
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistruct bh1750_chip_info;
388c2ecf20Sopenharmony_cistruct bh1750_data {
398c2ecf20Sopenharmony_ci	struct i2c_client *client;
408c2ecf20Sopenharmony_ci	struct mutex lock;
418c2ecf20Sopenharmony_ci	const struct bh1750_chip_info *chip_info;
428c2ecf20Sopenharmony_ci	u16 mtreg;
438c2ecf20Sopenharmony_ci};
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistruct bh1750_chip_info {
468c2ecf20Sopenharmony_ci	u16 mtreg_min;
478c2ecf20Sopenharmony_ci	u16 mtreg_max;
488c2ecf20Sopenharmony_ci	u16 mtreg_default;
498c2ecf20Sopenharmony_ci	int mtreg_to_usec;
508c2ecf20Sopenharmony_ci	int mtreg_to_scale;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/*
538c2ecf20Sopenharmony_ci	 * For BH1710/BH1721 all possible integration time values won't fit
548c2ecf20Sopenharmony_ci	 * into one page so displaying is limited to every second one.
558c2ecf20Sopenharmony_ci	 * Note, that user can still write proper values which were not
568c2ecf20Sopenharmony_ci	 * listed.
578c2ecf20Sopenharmony_ci	 */
588c2ecf20Sopenharmony_ci	int inc;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	u16 int_time_low_mask;
618c2ecf20Sopenharmony_ci	u16 int_time_high_mask;
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic const struct bh1750_chip_info bh1750_chip_info_tbl[] = {
658c2ecf20Sopenharmony_ci	[BH1710] = { 140, 1022, 300, 400,  250000000, 2, 0x001F, 0x03E0 },
668c2ecf20Sopenharmony_ci	[BH1721] = { 140, 1020, 300, 400,  250000000, 2, 0x0010, 0x03E0 },
678c2ecf20Sopenharmony_ci	[BH1750] = { 31,  254,  69,  1740, 57500000,  1, 0x001F, 0x00E0 },
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistatic int bh1750_change_int_time(struct bh1750_data *data, int usec)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	int ret;
738c2ecf20Sopenharmony_ci	u16 val;
748c2ecf20Sopenharmony_ci	u8 regval;
758c2ecf20Sopenharmony_ci	const struct bh1750_chip_info *chip_info = data->chip_info;
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	if ((usec % chip_info->mtreg_to_usec) != 0)
788c2ecf20Sopenharmony_ci		return -EINVAL;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	val = usec / chip_info->mtreg_to_usec;
818c2ecf20Sopenharmony_ci	if (val < chip_info->mtreg_min || val > chip_info->mtreg_max)
828c2ecf20Sopenharmony_ci		return -EINVAL;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
858c2ecf20Sopenharmony_ci	if (ret < 0)
868c2ecf20Sopenharmony_ci		return ret;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	regval = (val & chip_info->int_time_high_mask) >> 5;
898c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte(data->client,
908c2ecf20Sopenharmony_ci				   BH1750_CHANGE_INT_TIME_H_BIT | regval);
918c2ecf20Sopenharmony_ci	if (ret < 0)
928c2ecf20Sopenharmony_ci		return ret;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	regval = val & chip_info->int_time_low_mask;
958c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte(data->client,
968c2ecf20Sopenharmony_ci				   BH1750_CHANGE_INT_TIME_L_BIT | regval);
978c2ecf20Sopenharmony_ci	if (ret < 0)
988c2ecf20Sopenharmony_ci		return ret;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	data->mtreg = val;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	return 0;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int bh1750_read(struct bh1750_data *data, int *val)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	int ret;
1088c2ecf20Sopenharmony_ci	__be16 result;
1098c2ecf20Sopenharmony_ci	const struct bh1750_chip_info *chip_info = data->chip_info;
1108c2ecf20Sopenharmony_ci	unsigned long delay = chip_info->mtreg_to_usec * data->mtreg;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	/*
1138c2ecf20Sopenharmony_ci	 * BH1721 will enter continuous mode on receiving this command.
1148c2ecf20Sopenharmony_ci	 * Note, that this eliminates need for bh1750_resume().
1158c2ecf20Sopenharmony_ci	 */
1168c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte(data->client, BH1750_ONE_TIME_H_RES_MODE);
1178c2ecf20Sopenharmony_ci	if (ret < 0)
1188c2ecf20Sopenharmony_ci		return ret;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	usleep_range(delay + 15000, delay + 40000);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	ret = i2c_master_recv(data->client, (char *)&result, 2);
1238c2ecf20Sopenharmony_ci	if (ret < 0)
1248c2ecf20Sopenharmony_ci		return ret;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	*val = be16_to_cpu(result);
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	return 0;
1298c2ecf20Sopenharmony_ci}
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistatic int bh1750_read_raw(struct iio_dev *indio_dev,
1328c2ecf20Sopenharmony_ci			   struct iio_chan_spec const *chan,
1338c2ecf20Sopenharmony_ci			   int *val, int *val2, long mask)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	int ret, tmp;
1368c2ecf20Sopenharmony_ci	struct bh1750_data *data = iio_priv(indio_dev);
1378c2ecf20Sopenharmony_ci	const struct bh1750_chip_info *chip_info = data->chip_info;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	switch (mask) {
1408c2ecf20Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
1418c2ecf20Sopenharmony_ci		switch (chan->type) {
1428c2ecf20Sopenharmony_ci		case IIO_LIGHT:
1438c2ecf20Sopenharmony_ci			mutex_lock(&data->lock);
1448c2ecf20Sopenharmony_ci			ret = bh1750_read(data, val);
1458c2ecf20Sopenharmony_ci			mutex_unlock(&data->lock);
1468c2ecf20Sopenharmony_ci			if (ret < 0)
1478c2ecf20Sopenharmony_ci				return ret;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci			return IIO_VAL_INT;
1508c2ecf20Sopenharmony_ci		default:
1518c2ecf20Sopenharmony_ci			return -EINVAL;
1528c2ecf20Sopenharmony_ci		}
1538c2ecf20Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
1548c2ecf20Sopenharmony_ci		tmp = chip_info->mtreg_to_scale / data->mtreg;
1558c2ecf20Sopenharmony_ci		*val = tmp / 1000000;
1568c2ecf20Sopenharmony_ci		*val2 = tmp % 1000000;
1578c2ecf20Sopenharmony_ci		return IIO_VAL_INT_PLUS_MICRO;
1588c2ecf20Sopenharmony_ci	case IIO_CHAN_INFO_INT_TIME:
1598c2ecf20Sopenharmony_ci		*val = 0;
1608c2ecf20Sopenharmony_ci		*val2 = chip_info->mtreg_to_usec * data->mtreg;
1618c2ecf20Sopenharmony_ci		return IIO_VAL_INT_PLUS_MICRO;
1628c2ecf20Sopenharmony_ci	default:
1638c2ecf20Sopenharmony_ci		return -EINVAL;
1648c2ecf20Sopenharmony_ci	}
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic int bh1750_write_raw(struct iio_dev *indio_dev,
1688c2ecf20Sopenharmony_ci			    struct iio_chan_spec const *chan,
1698c2ecf20Sopenharmony_ci			    int val, int val2, long mask)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	int ret;
1728c2ecf20Sopenharmony_ci	struct bh1750_data *data = iio_priv(indio_dev);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	switch (mask) {
1758c2ecf20Sopenharmony_ci	case IIO_CHAN_INFO_INT_TIME:
1768c2ecf20Sopenharmony_ci		if (val != 0)
1778c2ecf20Sopenharmony_ci			return -EINVAL;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci		mutex_lock(&data->lock);
1808c2ecf20Sopenharmony_ci		ret = bh1750_change_int_time(data, val2);
1818c2ecf20Sopenharmony_ci		mutex_unlock(&data->lock);
1828c2ecf20Sopenharmony_ci		return ret;
1838c2ecf20Sopenharmony_ci	default:
1848c2ecf20Sopenharmony_ci		return -EINVAL;
1858c2ecf20Sopenharmony_ci	}
1868c2ecf20Sopenharmony_ci}
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_cistatic ssize_t bh1750_show_int_time_available(struct device *dev,
1898c2ecf20Sopenharmony_ci		struct device_attribute *attr, char *buf)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	int i;
1928c2ecf20Sopenharmony_ci	size_t len = 0;
1938c2ecf20Sopenharmony_ci	struct bh1750_data *data = iio_priv(dev_to_iio_dev(dev));
1948c2ecf20Sopenharmony_ci	const struct bh1750_chip_info *chip_info = data->chip_info;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	for (i = chip_info->mtreg_min; i <= chip_info->mtreg_max; i += chip_info->inc)
1978c2ecf20Sopenharmony_ci		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
1988c2ecf20Sopenharmony_ci				 chip_info->mtreg_to_usec * i);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	buf[len - 1] = '\n';
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	return len;
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cistatic IIO_DEV_ATTR_INT_TIME_AVAIL(bh1750_show_int_time_available);
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_cistatic struct attribute *bh1750_attributes[] = {
2088c2ecf20Sopenharmony_ci	&iio_dev_attr_integration_time_available.dev_attr.attr,
2098c2ecf20Sopenharmony_ci	NULL,
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic const struct attribute_group bh1750_attribute_group = {
2138c2ecf20Sopenharmony_ci	.attrs = bh1750_attributes,
2148c2ecf20Sopenharmony_ci};
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_cistatic const struct iio_info bh1750_info = {
2178c2ecf20Sopenharmony_ci	.attrs = &bh1750_attribute_group,
2188c2ecf20Sopenharmony_ci	.read_raw = bh1750_read_raw,
2198c2ecf20Sopenharmony_ci	.write_raw = bh1750_write_raw,
2208c2ecf20Sopenharmony_ci};
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic const struct iio_chan_spec bh1750_channels[] = {
2238c2ecf20Sopenharmony_ci	{
2248c2ecf20Sopenharmony_ci		.type = IIO_LIGHT,
2258c2ecf20Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
2268c2ecf20Sopenharmony_ci				      BIT(IIO_CHAN_INFO_SCALE) |
2278c2ecf20Sopenharmony_ci				      BIT(IIO_CHAN_INFO_INT_TIME)
2288c2ecf20Sopenharmony_ci	}
2298c2ecf20Sopenharmony_ci};
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_cistatic int bh1750_probe(struct i2c_client *client,
2328c2ecf20Sopenharmony_ci			const struct i2c_device_id *id)
2338c2ecf20Sopenharmony_ci{
2348c2ecf20Sopenharmony_ci	int ret, usec;
2358c2ecf20Sopenharmony_ci	struct bh1750_data *data;
2368c2ecf20Sopenharmony_ci	struct iio_dev *indio_dev;
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
2398c2ecf20Sopenharmony_ci				I2C_FUNC_SMBUS_WRITE_BYTE))
2408c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
2438c2ecf20Sopenharmony_ci	if (!indio_dev)
2448c2ecf20Sopenharmony_ci		return -ENOMEM;
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	data = iio_priv(indio_dev);
2478c2ecf20Sopenharmony_ci	i2c_set_clientdata(client, indio_dev);
2488c2ecf20Sopenharmony_ci	data->client = client;
2498c2ecf20Sopenharmony_ci	data->chip_info = &bh1750_chip_info_tbl[id->driver_data];
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	usec = data->chip_info->mtreg_to_usec * data->chip_info->mtreg_default;
2528c2ecf20Sopenharmony_ci	ret = bh1750_change_int_time(data, usec);
2538c2ecf20Sopenharmony_ci	if (ret < 0)
2548c2ecf20Sopenharmony_ci		return ret;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	mutex_init(&data->lock);
2578c2ecf20Sopenharmony_ci	indio_dev->info = &bh1750_info;
2588c2ecf20Sopenharmony_ci	indio_dev->name = id->name;
2598c2ecf20Sopenharmony_ci	indio_dev->channels = bh1750_channels;
2608c2ecf20Sopenharmony_ci	indio_dev->num_channels = ARRAY_SIZE(bh1750_channels);
2618c2ecf20Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	return iio_device_register(indio_dev);
2648c2ecf20Sopenharmony_ci}
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_cistatic int bh1750_remove(struct i2c_client *client)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	struct iio_dev *indio_dev = i2c_get_clientdata(client);
2698c2ecf20Sopenharmony_ci	struct bh1750_data *data = iio_priv(indio_dev);
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	iio_device_unregister(indio_dev);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	mutex_lock(&data->lock);
2748c2ecf20Sopenharmony_ci	i2c_smbus_write_byte(client, BH1750_POWER_DOWN);
2758c2ecf20Sopenharmony_ci	mutex_unlock(&data->lock);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	return 0;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cistatic int __maybe_unused bh1750_suspend(struct device *dev)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	int ret;
2838c2ecf20Sopenharmony_ci	struct bh1750_data *data =
2848c2ecf20Sopenharmony_ci		iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	/*
2878c2ecf20Sopenharmony_ci	 * This is mainly for BH1721 which doesn't enter power down
2888c2ecf20Sopenharmony_ci	 * mode automatically.
2898c2ecf20Sopenharmony_ci	 */
2908c2ecf20Sopenharmony_ci	mutex_lock(&data->lock);
2918c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
2928c2ecf20Sopenharmony_ci	mutex_unlock(&data->lock);
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	return ret;
2958c2ecf20Sopenharmony_ci}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(bh1750_pm_ops, bh1750_suspend, NULL);
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic const struct i2c_device_id bh1750_id[] = {
3008c2ecf20Sopenharmony_ci	{ "bh1710", BH1710 },
3018c2ecf20Sopenharmony_ci	{ "bh1715", BH1750 },
3028c2ecf20Sopenharmony_ci	{ "bh1721", BH1721 },
3038c2ecf20Sopenharmony_ci	{ "bh1750", BH1750 },
3048c2ecf20Sopenharmony_ci	{ "bh1751", BH1750 },
3058c2ecf20Sopenharmony_ci	{ }
3068c2ecf20Sopenharmony_ci};
3078c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, bh1750_id);
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistatic const struct of_device_id bh1750_of_match[] = {
3108c2ecf20Sopenharmony_ci	{ .compatible = "rohm,bh1710", },
3118c2ecf20Sopenharmony_ci	{ .compatible = "rohm,bh1715", },
3128c2ecf20Sopenharmony_ci	{ .compatible = "rohm,bh1721", },
3138c2ecf20Sopenharmony_ci	{ .compatible = "rohm,bh1750", },
3148c2ecf20Sopenharmony_ci	{ .compatible = "rohm,bh1751", },
3158c2ecf20Sopenharmony_ci	{ }
3168c2ecf20Sopenharmony_ci};
3178c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, bh1750_of_match);
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistatic struct i2c_driver bh1750_driver = {
3208c2ecf20Sopenharmony_ci	.driver = {
3218c2ecf20Sopenharmony_ci		.name = "bh1750",
3228c2ecf20Sopenharmony_ci		.of_match_table = bh1750_of_match,
3238c2ecf20Sopenharmony_ci		.pm = &bh1750_pm_ops,
3248c2ecf20Sopenharmony_ci	},
3258c2ecf20Sopenharmony_ci	.probe = bh1750_probe,
3268c2ecf20Sopenharmony_ci	.remove = bh1750_remove,
3278c2ecf20Sopenharmony_ci	.id_table = bh1750_id,
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci};
3308c2ecf20Sopenharmony_cimodule_i2c_driver(bh1750_driver);
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ciMODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
3338c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ROHM BH1710/BH1715/BH1721/BH1750/BH1751 als driver");
3348c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
335