18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * isl29125.c - Support for Intersil ISL29125 RGB light sensor 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * RGB light sensor with 16-bit channels for red, green, blue); 88c2ecf20Sopenharmony_ci * 7-bit I2C slave address 0x44 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * TODO: interrupt support, IR compensation, thresholds, 12bit 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/i2c.h> 158c2ecf20Sopenharmony_ci#include <linux/delay.h> 168c2ecf20Sopenharmony_ci#include <linux/pm.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 198c2ecf20Sopenharmony_ci#include <linux/iio/sysfs.h> 208c2ecf20Sopenharmony_ci#include <linux/iio/trigger_consumer.h> 218c2ecf20Sopenharmony_ci#include <linux/iio/buffer.h> 228c2ecf20Sopenharmony_ci#include <linux/iio/triggered_buffer.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define ISL29125_DRV_NAME "isl29125" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define ISL29125_DEVICE_ID 0x00 278c2ecf20Sopenharmony_ci#define ISL29125_CONF1 0x01 288c2ecf20Sopenharmony_ci#define ISL29125_CONF2 0x02 298c2ecf20Sopenharmony_ci#define ISL29125_CONF3 0x03 308c2ecf20Sopenharmony_ci#define ISL29125_STATUS 0x08 318c2ecf20Sopenharmony_ci#define ISL29125_GREEN_DATA 0x09 328c2ecf20Sopenharmony_ci#define ISL29125_RED_DATA 0x0b 338c2ecf20Sopenharmony_ci#define ISL29125_BLUE_DATA 0x0d 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define ISL29125_ID 0x7d 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define ISL29125_MODE_MASK GENMASK(2, 0) 388c2ecf20Sopenharmony_ci#define ISL29125_MODE_PD 0x0 398c2ecf20Sopenharmony_ci#define ISL29125_MODE_G 0x1 408c2ecf20Sopenharmony_ci#define ISL29125_MODE_R 0x2 418c2ecf20Sopenharmony_ci#define ISL29125_MODE_B 0x3 428c2ecf20Sopenharmony_ci#define ISL29125_MODE_RGB 0x5 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define ISL29125_SENSING_RANGE_0 5722 /* 375 lux full range */ 458c2ecf20Sopenharmony_ci#define ISL29125_SENSING_RANGE_1 152590 /* 10k lux full range */ 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define ISL29125_MODE_RANGE BIT(3) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define ISL29125_STATUS_CONV BIT(1) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistruct isl29125_data { 528c2ecf20Sopenharmony_ci struct i2c_client *client; 538c2ecf20Sopenharmony_ci u8 conf1; 548c2ecf20Sopenharmony_ci /* Ensure timestamp is naturally aligned */ 558c2ecf20Sopenharmony_ci struct { 568c2ecf20Sopenharmony_ci u16 chans[3]; 578c2ecf20Sopenharmony_ci s64 timestamp __aligned(8); 588c2ecf20Sopenharmony_ci } scan; 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define ISL29125_CHANNEL(_color, _si) { \ 628c2ecf20Sopenharmony_ci .type = IIO_INTENSITY, \ 638c2ecf20Sopenharmony_ci .modified = 1, \ 648c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 658c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 668c2ecf20Sopenharmony_ci .channel2 = IIO_MOD_LIGHT_##_color, \ 678c2ecf20Sopenharmony_ci .scan_index = _si, \ 688c2ecf20Sopenharmony_ci .scan_type = { \ 698c2ecf20Sopenharmony_ci .sign = 'u', \ 708c2ecf20Sopenharmony_ci .realbits = 16, \ 718c2ecf20Sopenharmony_ci .storagebits = 16, \ 728c2ecf20Sopenharmony_ci .endianness = IIO_CPU, \ 738c2ecf20Sopenharmony_ci }, \ 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic const struct iio_chan_spec isl29125_channels[] = { 778c2ecf20Sopenharmony_ci ISL29125_CHANNEL(GREEN, 0), 788c2ecf20Sopenharmony_ci ISL29125_CHANNEL(RED, 1), 798c2ecf20Sopenharmony_ci ISL29125_CHANNEL(BLUE, 2), 808c2ecf20Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(3), 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic const struct { 848c2ecf20Sopenharmony_ci u8 mode, data; 858c2ecf20Sopenharmony_ci} isl29125_regs[] = { 868c2ecf20Sopenharmony_ci {ISL29125_MODE_G, ISL29125_GREEN_DATA}, 878c2ecf20Sopenharmony_ci {ISL29125_MODE_R, ISL29125_RED_DATA}, 888c2ecf20Sopenharmony_ci {ISL29125_MODE_B, ISL29125_BLUE_DATA}, 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic int isl29125_read_data(struct isl29125_data *data, int si) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci int tries = 5; 948c2ecf20Sopenharmony_ci int ret; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 978c2ecf20Sopenharmony_ci data->conf1 | isl29125_regs[si].mode); 988c2ecf20Sopenharmony_ci if (ret < 0) 998c2ecf20Sopenharmony_ci return ret; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci msleep(101); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci while (tries--) { 1048c2ecf20Sopenharmony_ci ret = i2c_smbus_read_byte_data(data->client, ISL29125_STATUS); 1058c2ecf20Sopenharmony_ci if (ret < 0) 1068c2ecf20Sopenharmony_ci goto fail; 1078c2ecf20Sopenharmony_ci if (ret & ISL29125_STATUS_CONV) 1088c2ecf20Sopenharmony_ci break; 1098c2ecf20Sopenharmony_ci msleep(20); 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if (tries < 0) { 1138c2ecf20Sopenharmony_ci dev_err(&data->client->dev, "data not ready\n"); 1148c2ecf20Sopenharmony_ci ret = -EIO; 1158c2ecf20Sopenharmony_ci goto fail; 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci ret = i2c_smbus_read_word_data(data->client, isl29125_regs[si].data); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cifail: 1218c2ecf20Sopenharmony_ci i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, data->conf1); 1228c2ecf20Sopenharmony_ci return ret; 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic int isl29125_read_raw(struct iio_dev *indio_dev, 1268c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1278c2ecf20Sopenharmony_ci int *val, int *val2, long mask) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(indio_dev); 1308c2ecf20Sopenharmony_ci int ret; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci switch (mask) { 1338c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1348c2ecf20Sopenharmony_ci ret = iio_device_claim_direct_mode(indio_dev); 1358c2ecf20Sopenharmony_ci if (ret) 1368c2ecf20Sopenharmony_ci return ret; 1378c2ecf20Sopenharmony_ci ret = isl29125_read_data(data, chan->scan_index); 1388c2ecf20Sopenharmony_ci iio_device_release_direct_mode(indio_dev); 1398c2ecf20Sopenharmony_ci if (ret < 0) 1408c2ecf20Sopenharmony_ci return ret; 1418c2ecf20Sopenharmony_ci *val = ret; 1428c2ecf20Sopenharmony_ci return IIO_VAL_INT; 1438c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1448c2ecf20Sopenharmony_ci *val = 0; 1458c2ecf20Sopenharmony_ci if (data->conf1 & ISL29125_MODE_RANGE) 1468c2ecf20Sopenharmony_ci *val2 = ISL29125_SENSING_RANGE_1; /*10k lux full range*/ 1478c2ecf20Sopenharmony_ci else 1488c2ecf20Sopenharmony_ci *val2 = ISL29125_SENSING_RANGE_0; /*375 lux full range*/ 1498c2ecf20Sopenharmony_ci return IIO_VAL_INT_PLUS_MICRO; 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci return -EINVAL; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic int isl29125_write_raw(struct iio_dev *indio_dev, 1558c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1568c2ecf20Sopenharmony_ci int val, int val2, long mask) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(indio_dev); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci switch (mask) { 1618c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1628c2ecf20Sopenharmony_ci if (val != 0) 1638c2ecf20Sopenharmony_ci return -EINVAL; 1648c2ecf20Sopenharmony_ci if (val2 == ISL29125_SENSING_RANGE_1) 1658c2ecf20Sopenharmony_ci data->conf1 |= ISL29125_MODE_RANGE; 1668c2ecf20Sopenharmony_ci else if (val2 == ISL29125_SENSING_RANGE_0) 1678c2ecf20Sopenharmony_ci data->conf1 &= ~ISL29125_MODE_RANGE; 1688c2ecf20Sopenharmony_ci else 1698c2ecf20Sopenharmony_ci return -EINVAL; 1708c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 1718c2ecf20Sopenharmony_ci data->conf1); 1728c2ecf20Sopenharmony_ci default: 1738c2ecf20Sopenharmony_ci return -EINVAL; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic irqreturn_t isl29125_trigger_handler(int irq, void *p) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci struct iio_poll_func *pf = p; 1808c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = pf->indio_dev; 1818c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(indio_dev); 1828c2ecf20Sopenharmony_ci int i, j = 0; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci for_each_set_bit(i, indio_dev->active_scan_mask, 1858c2ecf20Sopenharmony_ci indio_dev->masklength) { 1868c2ecf20Sopenharmony_ci int ret = i2c_smbus_read_word_data(data->client, 1878c2ecf20Sopenharmony_ci isl29125_regs[i].data); 1888c2ecf20Sopenharmony_ci if (ret < 0) 1898c2ecf20Sopenharmony_ci goto done; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci data->scan.chans[j++] = ret; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, 1958c2ecf20Sopenharmony_ci iio_get_time_ns(indio_dev)); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cidone: 1988c2ecf20Sopenharmony_ci iio_trigger_notify_done(indio_dev->trig); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic IIO_CONST_ATTR(scale_available, "0.005722 0.152590"); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic struct attribute *isl29125_attributes[] = { 2068c2ecf20Sopenharmony_ci &iio_const_attr_scale_available.dev_attr.attr, 2078c2ecf20Sopenharmony_ci NULL 2088c2ecf20Sopenharmony_ci}; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic const struct attribute_group isl29125_attribute_group = { 2118c2ecf20Sopenharmony_ci .attrs = isl29125_attributes, 2128c2ecf20Sopenharmony_ci}; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic const struct iio_info isl29125_info = { 2158c2ecf20Sopenharmony_ci .read_raw = isl29125_read_raw, 2168c2ecf20Sopenharmony_ci .write_raw = isl29125_write_raw, 2178c2ecf20Sopenharmony_ci .attrs = &isl29125_attribute_group, 2188c2ecf20Sopenharmony_ci}; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic int isl29125_buffer_postenable(struct iio_dev *indio_dev) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(indio_dev); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci data->conf1 |= ISL29125_MODE_RGB; 2258c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 2268c2ecf20Sopenharmony_ci data->conf1); 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic int isl29125_buffer_predisable(struct iio_dev *indio_dev) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(indio_dev); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci data->conf1 &= ~ISL29125_MODE_MASK; 2348c2ecf20Sopenharmony_ci data->conf1 |= ISL29125_MODE_PD; 2358c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 2368c2ecf20Sopenharmony_ci data->conf1); 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cistatic const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = { 2408c2ecf20Sopenharmony_ci .postenable = isl29125_buffer_postenable, 2418c2ecf20Sopenharmony_ci .predisable = isl29125_buffer_predisable, 2428c2ecf20Sopenharmony_ci}; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic int isl29125_probe(struct i2c_client *client, 2458c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci struct isl29125_data *data; 2488c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 2498c2ecf20Sopenharmony_ci int ret; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 2528c2ecf20Sopenharmony_ci if (indio_dev == NULL) 2538c2ecf20Sopenharmony_ci return -ENOMEM; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci data = iio_priv(indio_dev); 2568c2ecf20Sopenharmony_ci i2c_set_clientdata(client, indio_dev); 2578c2ecf20Sopenharmony_ci data->client = client; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci indio_dev->info = &isl29125_info; 2608c2ecf20Sopenharmony_ci indio_dev->name = ISL29125_DRV_NAME; 2618c2ecf20Sopenharmony_ci indio_dev->channels = isl29125_channels; 2628c2ecf20Sopenharmony_ci indio_dev->num_channels = ARRAY_SIZE(isl29125_channels); 2638c2ecf20Sopenharmony_ci indio_dev->modes = INDIO_DIRECT_MODE; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci ret = i2c_smbus_read_byte_data(data->client, ISL29125_DEVICE_ID); 2668c2ecf20Sopenharmony_ci if (ret < 0) 2678c2ecf20Sopenharmony_ci return ret; 2688c2ecf20Sopenharmony_ci if (ret != ISL29125_ID) 2698c2ecf20Sopenharmony_ci return -ENODEV; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci data->conf1 = ISL29125_MODE_PD | ISL29125_MODE_RANGE; 2728c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 2738c2ecf20Sopenharmony_ci data->conf1); 2748c2ecf20Sopenharmony_ci if (ret < 0) 2758c2ecf20Sopenharmony_ci return ret; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, ISL29125_STATUS, 0); 2788c2ecf20Sopenharmony_ci if (ret < 0) 2798c2ecf20Sopenharmony_ci return ret; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci ret = iio_triggered_buffer_setup(indio_dev, NULL, 2828c2ecf20Sopenharmony_ci isl29125_trigger_handler, &isl29125_buffer_setup_ops); 2838c2ecf20Sopenharmony_ci if (ret < 0) 2848c2ecf20Sopenharmony_ci return ret; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci ret = iio_device_register(indio_dev); 2878c2ecf20Sopenharmony_ci if (ret < 0) 2888c2ecf20Sopenharmony_ci goto buffer_cleanup; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci return 0; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cibuffer_cleanup: 2938c2ecf20Sopenharmony_ci iio_triggered_buffer_cleanup(indio_dev); 2948c2ecf20Sopenharmony_ci return ret; 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic int isl29125_powerdown(struct isl29125_data *data) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 3008c2ecf20Sopenharmony_ci (data->conf1 & ~ISL29125_MODE_MASK) | ISL29125_MODE_PD); 3018c2ecf20Sopenharmony_ci} 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic int isl29125_remove(struct i2c_client *client) 3048c2ecf20Sopenharmony_ci{ 3058c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = i2c_get_clientdata(client); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci iio_device_unregister(indio_dev); 3088c2ecf20Sopenharmony_ci iio_triggered_buffer_cleanup(indio_dev); 3098c2ecf20Sopenharmony_ci isl29125_powerdown(iio_priv(indio_dev)); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci return 0; 3128c2ecf20Sopenharmony_ci} 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 3158c2ecf20Sopenharmony_cistatic int isl29125_suspend(struct device *dev) 3168c2ecf20Sopenharmony_ci{ 3178c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(i2c_get_clientdata( 3188c2ecf20Sopenharmony_ci to_i2c_client(dev))); 3198c2ecf20Sopenharmony_ci return isl29125_powerdown(data); 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_cistatic int isl29125_resume(struct device *dev) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci struct isl29125_data *data = iio_priv(i2c_get_clientdata( 3258c2ecf20Sopenharmony_ci to_i2c_client(dev))); 3268c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, 3278c2ecf20Sopenharmony_ci data->conf1); 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci#endif 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(isl29125_pm_ops, isl29125_suspend, isl29125_resume); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic const struct i2c_device_id isl29125_id[] = { 3348c2ecf20Sopenharmony_ci { "isl29125", 0 }, 3358c2ecf20Sopenharmony_ci { } 3368c2ecf20Sopenharmony_ci}; 3378c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, isl29125_id); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_cistatic struct i2c_driver isl29125_driver = { 3408c2ecf20Sopenharmony_ci .driver = { 3418c2ecf20Sopenharmony_ci .name = ISL29125_DRV_NAME, 3428c2ecf20Sopenharmony_ci .pm = &isl29125_pm_ops, 3438c2ecf20Sopenharmony_ci }, 3448c2ecf20Sopenharmony_ci .probe = isl29125_probe, 3458c2ecf20Sopenharmony_ci .remove = isl29125_remove, 3468c2ecf20Sopenharmony_ci .id_table = isl29125_id, 3478c2ecf20Sopenharmony_ci}; 3488c2ecf20Sopenharmony_cimodule_i2c_driver(isl29125_driver); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ciMODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 3518c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ISL29125 RGB light sensor driver"); 3528c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 353