Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 Capella Microsystems Inc.
0004  * Author: Kevin Tsai <ktsai@capellamicro.com>
0005  */
0006 
0007 #include <linux/acpi.h>
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/i2c.h>
0011 #include <linux/mutex.h>
0012 #include <linux/module.h>
0013 #include <linux/mod_devicetable.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/regulator/consumer.h>
0016 #include <linux/iio/iio.h>
0017 #include <linux/iio/sysfs.h>
0018 #include <linux/iio/events.h>
0019 #include <linux/init.h>
0020 
0021 /* Registers Address */
0022 #define CM32181_REG_ADDR_CMD        0x00
0023 #define CM32181_REG_ADDR_WH     0x01
0024 #define CM32181_REG_ADDR_WL     0x02
0025 #define CM32181_REG_ADDR_TEST       0x03
0026 #define CM32181_REG_ADDR_ALS        0x04
0027 #define CM32181_REG_ADDR_STATUS     0x06
0028 #define CM32181_REG_ADDR_ID     0x07
0029 
0030 /* Number of Configurable Registers */
0031 #define CM32181_CONF_REG_NUM        4
0032 
0033 /* CMD register */
0034 #define CM32181_CMD_ALS_DISABLE     BIT(0)
0035 #define CM32181_CMD_ALS_INT_EN      BIT(1)
0036 #define CM32181_CMD_ALS_THRES_WINDOW    BIT(2)
0037 
0038 #define CM32181_CMD_ALS_PERS_SHIFT  4
0039 #define CM32181_CMD_ALS_PERS_MASK   (0x03 << CM32181_CMD_ALS_PERS_SHIFT)
0040 #define CM32181_CMD_ALS_PERS_DEFAULT    (0x01 << CM32181_CMD_ALS_PERS_SHIFT)
0041 
0042 #define CM32181_CMD_ALS_IT_SHIFT    6
0043 #define CM32181_CMD_ALS_IT_MASK     (0x0F << CM32181_CMD_ALS_IT_SHIFT)
0044 #define CM32181_CMD_ALS_IT_DEFAULT  (0x00 << CM32181_CMD_ALS_IT_SHIFT)
0045 
0046 #define CM32181_CMD_ALS_SM_SHIFT    11
0047 #define CM32181_CMD_ALS_SM_MASK     (0x03 << CM32181_CMD_ALS_SM_SHIFT)
0048 #define CM32181_CMD_ALS_SM_DEFAULT  (0x01 << CM32181_CMD_ALS_SM_SHIFT)
0049 
0050 #define CM32181_LUX_PER_BIT     500 /* ALS_SM=01 IT=800ms */
0051 #define CM32181_LUX_PER_BIT_RESOLUTION  100000
0052 #define CM32181_LUX_PER_BIT_BASE_IT 800000  /* Based on IT=800ms */
0053 #define CM32181_CALIBSCALE_DEFAULT  100000
0054 #define CM32181_CALIBSCALE_RESOLUTION   100000
0055 
0056 #define SMBUS_ALERT_RESPONSE_ADDRESS    0x0c
0057 
0058 /* CPM0 Index 0: device-id (3218 or 32181), 1: Unknown, 2: init_regs_bitmap */
0059 #define CPM0_REGS_BITMAP        2
0060 #define CPM0_HEADER_SIZE        3
0061 
0062 /* CPM1 Index 0: lux_per_bit, 1: calibscale, 2: resolution (100000) */
0063 #define CPM1_LUX_PER_BIT        0
0064 #define CPM1_CALIBSCALE         1
0065 #define CPM1_SIZE           3
0066 
0067 /* CM3218 Family */
0068 static const int cm3218_als_it_bits[] = { 0, 1, 2, 3 };
0069 static const int cm3218_als_it_values[] = { 100000, 200000, 400000, 800000 };
0070 
0071 /* CM32181 Family */
0072 static const int cm32181_als_it_bits[] = { 12, 8, 0, 1, 2, 3 };
0073 static const int cm32181_als_it_values[] = {
0074     25000, 50000, 100000, 200000, 400000, 800000
0075 };
0076 
0077 struct cm32181_chip {
0078     struct i2c_client *client;
0079     struct device *dev;
0080     struct mutex lock;
0081     u16 conf_regs[CM32181_CONF_REG_NUM];
0082     unsigned long init_regs_bitmap;
0083     int calibscale;
0084     int lux_per_bit;
0085     int lux_per_bit_base_it;
0086     int num_als_it;
0087     const int *als_it_bits;
0088     const int *als_it_values;
0089 };
0090 
0091 static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2);
0092 
0093 #ifdef CONFIG_ACPI
0094 /**
0095  * cm32181_acpi_get_cpm() - Get CPM object from ACPI
0096  * @dev:    pointer of struct device.
0097  * @obj_name:   pointer of ACPI object name.
0098  * @values: pointer of array for return elements.
0099  * @count:  maximum size of return array.
0100  *
0101  * Convert ACPI CPM table to array.
0102  *
0103  * Return: -ENODEV for fail.  Otherwise is number of elements.
0104  */
0105 static int cm32181_acpi_get_cpm(struct device *dev, char *obj_name,
0106                 u64 *values, int count)
0107 {
0108     struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0109     union acpi_object *cpm, *elem;
0110     acpi_handle handle;
0111     acpi_status status;
0112     int i;
0113 
0114     handle = ACPI_HANDLE(dev);
0115     if (!handle)
0116         return -ENODEV;
0117 
0118     status = acpi_evaluate_object(handle, obj_name, NULL, &buffer);
0119     if (ACPI_FAILURE(status)) {
0120         dev_err(dev, "object %s not found\n", obj_name);
0121         return -ENODEV;
0122     }
0123 
0124     cpm = buffer.pointer;
0125     if (cpm->package.count > count)
0126         dev_warn(dev, "%s table contains %u values, only using first %d values\n",
0127              obj_name, cpm->package.count, count);
0128 
0129     count = min_t(int, cpm->package.count, count);
0130     for (i = 0; i < count; i++) {
0131         elem = &(cpm->package.elements[i]);
0132         values[i] = elem->integer.value;
0133     }
0134 
0135     kfree(buffer.pointer);
0136 
0137     return count;
0138 }
0139 
0140 static void cm32181_acpi_parse_cpm_tables(struct cm32181_chip *cm32181)
0141 {
0142     u64 vals[CPM0_HEADER_SIZE + CM32181_CONF_REG_NUM];
0143     struct device *dev = cm32181->dev;
0144     int i, count;
0145 
0146     count = cm32181_acpi_get_cpm(dev, "CPM0", vals, ARRAY_SIZE(vals));
0147     if (count <= CPM0_HEADER_SIZE)
0148         return;
0149 
0150     count -= CPM0_HEADER_SIZE;
0151 
0152     cm32181->init_regs_bitmap = vals[CPM0_REGS_BITMAP];
0153     cm32181->init_regs_bitmap &= GENMASK(count - 1, 0);
0154     for_each_set_bit(i, &cm32181->init_regs_bitmap, count)
0155         cm32181->conf_regs[i] = vals[CPM0_HEADER_SIZE + i];
0156 
0157     count = cm32181_acpi_get_cpm(dev, "CPM1", vals, ARRAY_SIZE(vals));
0158     if (count != CPM1_SIZE)
0159         return;
0160 
0161     cm32181->lux_per_bit = vals[CPM1_LUX_PER_BIT];
0162 
0163     /* Check for uncalibrated devices */
0164     if (vals[CPM1_CALIBSCALE] == CM32181_CALIBSCALE_DEFAULT)
0165         return;
0166 
0167     cm32181->calibscale = vals[CPM1_CALIBSCALE];
0168     /* CPM1 lux_per_bit is for the current it value */
0169     cm32181_read_als_it(cm32181, &cm32181->lux_per_bit_base_it);
0170 }
0171 #else
0172 static void cm32181_acpi_parse_cpm_tables(struct cm32181_chip *cm32181)
0173 {
0174 }
0175 #endif /* CONFIG_ACPI */
0176 
0177 /**
0178  * cm32181_reg_init() - Initialize CM32181 registers
0179  * @cm32181:    pointer of struct cm32181.
0180  *
0181  * Initialize CM32181 ambient light sensor register to default values.
0182  *
0183  * Return: 0 for success; otherwise for error code.
0184  */
0185 static int cm32181_reg_init(struct cm32181_chip *cm32181)
0186 {
0187     struct i2c_client *client = cm32181->client;
0188     int i;
0189     s32 ret;
0190 
0191     ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID);
0192     if (ret < 0)
0193         return ret;
0194 
0195     /* check device ID */
0196     switch (ret & 0xFF) {
0197     case 0x18: /* CM3218 */
0198         cm32181->num_als_it = ARRAY_SIZE(cm3218_als_it_bits);
0199         cm32181->als_it_bits = cm3218_als_it_bits;
0200         cm32181->als_it_values = cm3218_als_it_values;
0201         break;
0202     case 0x81: /* CM32181 */
0203     case 0x82: /* CM32182, fully compat. with CM32181 */
0204         cm32181->num_als_it = ARRAY_SIZE(cm32181_als_it_bits);
0205         cm32181->als_it_bits = cm32181_als_it_bits;
0206         cm32181->als_it_values = cm32181_als_it_values;
0207         break;
0208     default:
0209         return -ENODEV;
0210     }
0211 
0212     /* Default Values */
0213     cm32181->conf_regs[CM32181_REG_ADDR_CMD] =
0214             CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT;
0215     cm32181->init_regs_bitmap = BIT(CM32181_REG_ADDR_CMD);
0216     cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT;
0217     cm32181->lux_per_bit = CM32181_LUX_PER_BIT;
0218     cm32181->lux_per_bit_base_it = CM32181_LUX_PER_BIT_BASE_IT;
0219 
0220     if (ACPI_HANDLE(cm32181->dev))
0221         cm32181_acpi_parse_cpm_tables(cm32181);
0222 
0223     /* Initialize registers*/
0224     for_each_set_bit(i, &cm32181->init_regs_bitmap, CM32181_CONF_REG_NUM) {
0225         ret = i2c_smbus_write_word_data(client, i,
0226                         cm32181->conf_regs[i]);
0227         if (ret < 0)
0228             return ret;
0229     }
0230 
0231     return 0;
0232 }
0233 
0234 /**
0235  *  cm32181_read_als_it() - Get sensor integration time (ms)
0236  *  @cm32181:   pointer of struct cm32181
0237  *  @val2:  pointer of int to load the als_it value.
0238  *
0239  *  Report the current integration time in milliseconds.
0240  *
0241  *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
0242  */
0243 static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
0244 {
0245     u16 als_it;
0246     int i;
0247 
0248     als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD];
0249     als_it &= CM32181_CMD_ALS_IT_MASK;
0250     als_it >>= CM32181_CMD_ALS_IT_SHIFT;
0251     for (i = 0; i < cm32181->num_als_it; i++) {
0252         if (als_it == cm32181->als_it_bits[i]) {
0253             *val2 = cm32181->als_it_values[i];
0254             return IIO_VAL_INT_PLUS_MICRO;
0255         }
0256     }
0257 
0258     return -EINVAL;
0259 }
0260 
0261 /**
0262  * cm32181_write_als_it() - Write sensor integration time
0263  * @cm32181:    pointer of struct cm32181.
0264  * @val:    integration time by millisecond.
0265  *
0266  * Convert integration time (ms) to sensor value.
0267  *
0268  * Return: i2c_smbus_write_word_data command return value.
0269  */
0270 static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
0271 {
0272     struct i2c_client *client = cm32181->client;
0273     u16 als_it;
0274     int ret, i, n;
0275 
0276     n = cm32181->num_als_it;
0277     for (i = 0; i < n; i++)
0278         if (val <= cm32181->als_it_values[i])
0279             break;
0280     if (i >= n)
0281         i = n - 1;
0282 
0283     als_it = cm32181->als_it_bits[i];
0284     als_it <<= CM32181_CMD_ALS_IT_SHIFT;
0285 
0286     mutex_lock(&cm32181->lock);
0287     cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
0288         ~CM32181_CMD_ALS_IT_MASK;
0289     cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
0290         als_it;
0291     ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
0292             cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
0293     mutex_unlock(&cm32181->lock);
0294 
0295     return ret;
0296 }
0297 
0298 /**
0299  * cm32181_get_lux() - report current lux value
0300  * @cm32181:    pointer of struct cm32181.
0301  *
0302  * Convert sensor raw data to lux.  It depends on integration
0303  * time and calibscale variable.
0304  *
0305  * Return: Positive value is lux, otherwise is error code.
0306  */
0307 static int cm32181_get_lux(struct cm32181_chip *cm32181)
0308 {
0309     struct i2c_client *client = cm32181->client;
0310     int ret;
0311     int als_it;
0312     u64 lux;
0313 
0314     ret = cm32181_read_als_it(cm32181, &als_it);
0315     if (ret < 0)
0316         return -EINVAL;
0317 
0318     lux = cm32181->lux_per_bit;
0319     lux *= cm32181->lux_per_bit_base_it;
0320     lux = div_u64(lux, als_it);
0321 
0322     ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
0323     if (ret < 0)
0324         return ret;
0325 
0326     lux *= ret;
0327     lux *= cm32181->calibscale;
0328     lux = div_u64(lux, CM32181_CALIBSCALE_RESOLUTION);
0329     lux = div_u64(lux, CM32181_LUX_PER_BIT_RESOLUTION);
0330 
0331     if (lux > 0xFFFF)
0332         lux = 0xFFFF;
0333 
0334     return lux;
0335 }
0336 
0337 static int cm32181_read_raw(struct iio_dev *indio_dev,
0338                 struct iio_chan_spec const *chan,
0339                 int *val, int *val2, long mask)
0340 {
0341     struct cm32181_chip *cm32181 = iio_priv(indio_dev);
0342     int ret;
0343 
0344     switch (mask) {
0345     case IIO_CHAN_INFO_PROCESSED:
0346         ret = cm32181_get_lux(cm32181);
0347         if (ret < 0)
0348             return ret;
0349         *val = ret;
0350         return IIO_VAL_INT;
0351     case IIO_CHAN_INFO_CALIBSCALE:
0352         *val = cm32181->calibscale;
0353         return IIO_VAL_INT;
0354     case IIO_CHAN_INFO_INT_TIME:
0355         *val = 0;
0356         ret = cm32181_read_als_it(cm32181, val2);
0357         return ret;
0358     }
0359 
0360     return -EINVAL;
0361 }
0362 
0363 static int cm32181_write_raw(struct iio_dev *indio_dev,
0364                  struct iio_chan_spec const *chan,
0365                  int val, int val2, long mask)
0366 {
0367     struct cm32181_chip *cm32181 = iio_priv(indio_dev);
0368     int ret;
0369 
0370     switch (mask) {
0371     case IIO_CHAN_INFO_CALIBSCALE:
0372         cm32181->calibscale = val;
0373         return val;
0374     case IIO_CHAN_INFO_INT_TIME:
0375         ret = cm32181_write_als_it(cm32181, val2);
0376         return ret;
0377     }
0378 
0379     return -EINVAL;
0380 }
0381 
0382 /**
0383  * cm32181_get_it_available() - Get available ALS IT value
0384  * @dev:    pointer of struct device.
0385  * @attr:   pointer of struct device_attribute.
0386  * @buf:    pointer of return string buffer.
0387  *
0388  * Display the available integration time values by millisecond.
0389  *
0390  * Return: string length.
0391  */
0392 static ssize_t cm32181_get_it_available(struct device *dev,
0393             struct device_attribute *attr, char *buf)
0394 {
0395     struct cm32181_chip *cm32181 = iio_priv(dev_to_iio_dev(dev));
0396     int i, n, len;
0397 
0398     n = cm32181->num_als_it;
0399     for (i = 0, len = 0; i < n; i++)
0400         len += sprintf(buf + len, "0.%06u ", cm32181->als_it_values[i]);
0401     return len + sprintf(buf + len, "\n");
0402 }
0403 
0404 static const struct iio_chan_spec cm32181_channels[] = {
0405     {
0406         .type = IIO_LIGHT,
0407         .info_mask_separate =
0408             BIT(IIO_CHAN_INFO_PROCESSED) |
0409             BIT(IIO_CHAN_INFO_CALIBSCALE) |
0410             BIT(IIO_CHAN_INFO_INT_TIME),
0411     }
0412 };
0413 
0414 static IIO_DEVICE_ATTR(in_illuminance_integration_time_available,
0415             S_IRUGO, cm32181_get_it_available, NULL, 0);
0416 
0417 static struct attribute *cm32181_attributes[] = {
0418     &iio_dev_attr_in_illuminance_integration_time_available.dev_attr.attr,
0419     NULL,
0420 };
0421 
0422 static const struct attribute_group cm32181_attribute_group = {
0423     .attrs = cm32181_attributes
0424 };
0425 
0426 static const struct iio_info cm32181_info = {
0427     .read_raw       = &cm32181_read_raw,
0428     .write_raw      = &cm32181_write_raw,
0429     .attrs          = &cm32181_attribute_group,
0430 };
0431 
0432 static int cm32181_probe(struct i2c_client *client)
0433 {
0434     struct device *dev = &client->dev;
0435     struct cm32181_chip *cm32181;
0436     struct iio_dev *indio_dev;
0437     int ret;
0438 
0439     indio_dev = devm_iio_device_alloc(dev, sizeof(*cm32181));
0440     if (!indio_dev)
0441         return -ENOMEM;
0442 
0443     /*
0444      * Some ACPI systems list 2 I2C resources for the CM3218 sensor, the
0445      * SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address.
0446      * Detect this and take the following step to deal with it:
0447      * 1. When a SMBus Alert capable sensor has an Alert asserted, it will
0448      *    not respond on its actual I2C address. Read a byte from the ARA
0449      *    to clear any pending Alerts.
0450      * 2. Create a "dummy" client for the actual I2C address and
0451      *    use that client to communicate with the sensor.
0452      */
0453     if (ACPI_HANDLE(dev) && client->addr == SMBUS_ALERT_RESPONSE_ADDRESS) {
0454         struct i2c_board_info board_info = { .type = "dummy" };
0455 
0456         i2c_smbus_read_byte(client);
0457 
0458         client = i2c_acpi_new_device(dev, 1, &board_info);
0459         if (IS_ERR(client))
0460             return PTR_ERR(client);
0461     }
0462 
0463     i2c_set_clientdata(client, indio_dev);
0464 
0465     cm32181 = iio_priv(indio_dev);
0466     cm32181->client = client;
0467     cm32181->dev = dev;
0468 
0469     mutex_init(&cm32181->lock);
0470     indio_dev->channels = cm32181_channels;
0471     indio_dev->num_channels = ARRAY_SIZE(cm32181_channels);
0472     indio_dev->info = &cm32181_info;
0473     indio_dev->name = dev_name(dev);
0474     indio_dev->modes = INDIO_DIRECT_MODE;
0475 
0476     ret = cm32181_reg_init(cm32181);
0477     if (ret) {
0478         dev_err(dev, "%s: register init failed\n", __func__);
0479         return ret;
0480     }
0481 
0482     ret = devm_iio_device_register(dev, indio_dev);
0483     if (ret) {
0484         dev_err(dev, "%s: regist device failed\n", __func__);
0485         return ret;
0486     }
0487 
0488     return 0;
0489 }
0490 
0491 static int cm32181_suspend(struct device *dev)
0492 {
0493     struct i2c_client *client = to_i2c_client(dev);
0494 
0495     return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
0496                      CM32181_CMD_ALS_DISABLE);
0497 }
0498 
0499 static int cm32181_resume(struct device *dev)
0500 {
0501     struct i2c_client *client = to_i2c_client(dev);
0502     struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev));
0503 
0504     return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
0505                      cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
0506 }
0507 
0508 static DEFINE_SIMPLE_DEV_PM_OPS(cm32181_pm_ops, cm32181_suspend, cm32181_resume);
0509 
0510 static const struct of_device_id cm32181_of_match[] = {
0511     { .compatible = "capella,cm3218" },
0512     { .compatible = "capella,cm32181" },
0513     { }
0514 };
0515 MODULE_DEVICE_TABLE(of, cm32181_of_match);
0516 
0517 #ifdef CONFIG_ACPI
0518 static const struct acpi_device_id cm32181_acpi_match[] = {
0519     { "CPLM3218", 0 },
0520     { }
0521 };
0522 MODULE_DEVICE_TABLE(acpi, cm32181_acpi_match);
0523 #endif
0524 
0525 static struct i2c_driver cm32181_driver = {
0526     .driver = {
0527         .name   = "cm32181",
0528         .acpi_match_table = ACPI_PTR(cm32181_acpi_match),
0529         .of_match_table = cm32181_of_match,
0530         .pm = pm_sleep_ptr(&cm32181_pm_ops),
0531     },
0532     .probe_new  = cm32181_probe,
0533 };
0534 
0535 module_i2c_driver(cm32181_driver);
0536 
0537 MODULE_AUTHOR("Kevin Tsai <ktsai@capellamicro.com>");
0538 MODULE_DESCRIPTION("CM32181 ambient light sensor driver");
0539 MODULE_LICENSE("GPL");