Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2015 Intel Corporation
0004  *
0005  * Driver for TXC PA12203001 Proximity and Ambient Light Sensor.
0006  *
0007  * To do: Interrupt support.
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/acpi.h>
0013 #include <linux/delay.h>
0014 #include <linux/i2c.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 #include <linux/mutex.h>
0018 #include <linux/pm.h>
0019 #include <linux/pm_runtime.h>
0020 #include <linux/regmap.h>
0021 
0022 #define PA12203001_DRIVER_NAME  "pa12203001"
0023 
0024 #define PA12203001_REG_CFG0     0x00
0025 #define PA12203001_REG_CFG1     0x01
0026 #define PA12203001_REG_CFG2     0x02
0027 #define PA12203001_REG_CFG3     0x03
0028 
0029 #define PA12203001_REG_ADL      0x0b
0030 #define PA12203001_REG_PDH      0x0e
0031 
0032 #define PA12203001_REG_POFS     0x10
0033 #define PA12203001_REG_PSET     0x11
0034 
0035 #define PA12203001_ALS_EN_MASK      BIT(0)
0036 #define PA12203001_PX_EN_MASK       BIT(1)
0037 #define PA12203001_PX_NORMAL_MODE_MASK      GENMASK(7, 6)
0038 #define PA12203001_AFSR_MASK        GENMASK(5, 4)
0039 #define PA12203001_AFSR_SHIFT       4
0040 
0041 #define PA12203001_PSCAN            0x03
0042 
0043 /* als range 31000, ps, als disabled */
0044 #define PA12203001_REG_CFG0_DEFAULT     0x30
0045 
0046 /* led current: 100 mA */
0047 #define PA12203001_REG_CFG1_DEFAULT     0x20
0048 
0049 /* ps mode: normal, interrupts not active */
0050 #define PA12203001_REG_CFG2_DEFAULT     0xcc
0051 
0052 #define PA12203001_REG_CFG3_DEFAULT     0x00
0053 
0054 #define PA12203001_SLEEP_DELAY_MS       3000
0055 
0056 #define PA12203001_CHIP_ENABLE      0xff
0057 #define PA12203001_CHIP_DISABLE     0x00
0058 
0059 /* available scales: corresponding to [500, 4000, 7000, 31000]  lux */
0060 static const int pa12203001_scales[] = { 7629, 61036, 106813, 473029};
0061 
0062 struct pa12203001_data {
0063     struct i2c_client *client;
0064 
0065     /* protect device states */
0066     struct mutex lock;
0067 
0068     bool als_enabled;
0069     bool px_enabled;
0070     bool als_needs_enable;
0071     bool px_needs_enable;
0072 
0073     struct regmap *map;
0074 };
0075 
0076 static const struct {
0077     u8 reg;
0078     u8 val;
0079 } regvals[] = {
0080     {PA12203001_REG_CFG0, PA12203001_REG_CFG0_DEFAULT},
0081     {PA12203001_REG_CFG1, PA12203001_REG_CFG1_DEFAULT},
0082     {PA12203001_REG_CFG2, PA12203001_REG_CFG2_DEFAULT},
0083     {PA12203001_REG_CFG3, PA12203001_REG_CFG3_DEFAULT},
0084     {PA12203001_REG_PSET, PA12203001_PSCAN},
0085 };
0086 
0087 static IIO_CONST_ATTR(in_illuminance_scale_available,
0088               "0.007629 0.061036 0.106813 0.473029");
0089 
0090 static struct attribute *pa12203001_attrs[] = {
0091     &iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
0092     NULL
0093 };
0094 
0095 static const struct attribute_group pa12203001_attr_group = {
0096     .attrs = pa12203001_attrs,
0097 };
0098 
0099 static const struct iio_chan_spec pa12203001_channels[] = {
0100     {
0101         .type = IIO_LIGHT,
0102         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0103                       BIT(IIO_CHAN_INFO_SCALE),
0104     },
0105     {
0106         .type = IIO_PROXIMITY,
0107         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0108     }
0109 };
0110 
0111 static const struct regmap_range pa12203001_volatile_regs_ranges[] = {
0112     regmap_reg_range(PA12203001_REG_ADL, PA12203001_REG_ADL + 1),
0113     regmap_reg_range(PA12203001_REG_PDH, PA12203001_REG_PDH),
0114 };
0115 
0116 static const struct regmap_access_table pa12203001_volatile_regs = {
0117     .yes_ranges = pa12203001_volatile_regs_ranges,
0118     .n_yes_ranges = ARRAY_SIZE(pa12203001_volatile_regs_ranges),
0119 };
0120 
0121 static const struct regmap_config pa12203001_regmap_config = {
0122     .reg_bits = 8,
0123     .val_bits = 8,
0124     .max_register = PA12203001_REG_PSET,
0125     .cache_type = REGCACHE_RBTREE,
0126     .volatile_table = &pa12203001_volatile_regs,
0127 };
0128 
0129 static inline int pa12203001_als_enable(struct pa12203001_data *data, u8 enable)
0130 {
0131     int ret;
0132 
0133     ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
0134                  PA12203001_ALS_EN_MASK, enable);
0135     if (ret < 0)
0136         return ret;
0137 
0138     data->als_enabled = !!enable;
0139 
0140     return 0;
0141 }
0142 
0143 static inline int pa12203001_px_enable(struct pa12203001_data *data, u8 enable)
0144 {
0145     int ret;
0146 
0147     ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
0148                  PA12203001_PX_EN_MASK, enable);
0149     if (ret < 0)
0150         return ret;
0151 
0152     data->px_enabled = !!enable;
0153 
0154     return 0;
0155 }
0156 
0157 static int pa12203001_set_power_state(struct pa12203001_data *data, bool on,
0158                       u8 mask)
0159 {
0160 #ifdef CONFIG_PM
0161     int ret;
0162 
0163     if (on && (mask & PA12203001_ALS_EN_MASK)) {
0164         mutex_lock(&data->lock);
0165         if (data->px_enabled) {
0166             ret = pa12203001_als_enable(data,
0167                             PA12203001_ALS_EN_MASK);
0168             if (ret < 0)
0169                 goto err;
0170         } else {
0171             data->als_needs_enable = true;
0172         }
0173         mutex_unlock(&data->lock);
0174     }
0175 
0176     if (on && (mask & PA12203001_PX_EN_MASK)) {
0177         mutex_lock(&data->lock);
0178         if (data->als_enabled) {
0179             ret = pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
0180             if (ret < 0)
0181                 goto err;
0182         } else {
0183             data->px_needs_enable = true;
0184         }
0185         mutex_unlock(&data->lock);
0186     }
0187 
0188     if (on) {
0189         ret = pm_runtime_resume_and_get(&data->client->dev);
0190 
0191     } else {
0192         pm_runtime_mark_last_busy(&data->client->dev);
0193         ret = pm_runtime_put_autosuspend(&data->client->dev);
0194     }
0195 
0196     return ret;
0197 
0198 err:
0199     mutex_unlock(&data->lock);
0200     return ret;
0201 
0202 #endif
0203     return 0;
0204 }
0205 
0206 static int pa12203001_read_raw(struct iio_dev *indio_dev,
0207                    struct iio_chan_spec const *chan, int *val,
0208                    int *val2, long mask)
0209 {
0210     struct pa12203001_data *data = iio_priv(indio_dev);
0211     int ret;
0212     u8 dev_mask;
0213     unsigned int reg_byte;
0214     __le16 reg_word;
0215 
0216     switch (mask) {
0217     case IIO_CHAN_INFO_RAW:
0218         switch (chan->type) {
0219         case IIO_LIGHT:
0220             dev_mask = PA12203001_ALS_EN_MASK;
0221             ret = pa12203001_set_power_state(data, true, dev_mask);
0222             if (ret < 0)
0223                 return ret;
0224             /*
0225              * ALS ADC value is stored in registers
0226              * PA12203001_REG_ADL and in PA12203001_REG_ADL + 1.
0227              */
0228             ret = regmap_bulk_read(data->map, PA12203001_REG_ADL,
0229                            &reg_word, 2);
0230             if (ret < 0)
0231                 goto reg_err;
0232 
0233             *val = le16_to_cpu(reg_word);
0234             ret = pa12203001_set_power_state(data, false, dev_mask);
0235             if (ret < 0)
0236                 return ret;
0237             break;
0238         case IIO_PROXIMITY:
0239             dev_mask = PA12203001_PX_EN_MASK;
0240             ret = pa12203001_set_power_state(data, true, dev_mask);
0241             if (ret < 0)
0242                 return ret;
0243             ret = regmap_read(data->map, PA12203001_REG_PDH,
0244                       &reg_byte);
0245             if (ret < 0)
0246                 goto reg_err;
0247 
0248             *val = reg_byte;
0249             ret = pa12203001_set_power_state(data, false, dev_mask);
0250             if (ret < 0)
0251                 return ret;
0252             break;
0253         default:
0254             return -EINVAL;
0255         }
0256         return IIO_VAL_INT;
0257     case IIO_CHAN_INFO_SCALE:
0258         ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
0259         if (ret < 0)
0260             return ret;
0261         *val = 0;
0262         reg_byte = (reg_byte & PA12203001_AFSR_MASK);
0263         *val2 = pa12203001_scales[reg_byte >> 4];
0264         return IIO_VAL_INT_PLUS_MICRO;
0265     default:
0266         return -EINVAL;
0267     }
0268 
0269 reg_err:
0270     pa12203001_set_power_state(data, false, dev_mask);
0271     return ret;
0272 }
0273 
0274 static int pa12203001_write_raw(struct iio_dev *indio_dev,
0275                 struct iio_chan_spec const *chan, int val,
0276                 int val2, long mask)
0277 {
0278     struct pa12203001_data *data = iio_priv(indio_dev);
0279     int i, ret, new_val;
0280     unsigned int reg_byte;
0281 
0282     switch (mask) {
0283     case IIO_CHAN_INFO_SCALE:
0284         ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
0285         if (val != 0 || ret < 0)
0286             return -EINVAL;
0287         for (i = 0; i < ARRAY_SIZE(pa12203001_scales); i++) {
0288             if (val2 == pa12203001_scales[i]) {
0289                 new_val = i << PA12203001_AFSR_SHIFT;
0290                 return regmap_update_bits(data->map,
0291                               PA12203001_REG_CFG0,
0292                               PA12203001_AFSR_MASK,
0293                               new_val);
0294             }
0295         }
0296         break;
0297     default:
0298         break;
0299     }
0300 
0301     return -EINVAL;
0302 }
0303 
0304 static const struct iio_info pa12203001_info = {
0305     .read_raw = pa12203001_read_raw,
0306     .write_raw = pa12203001_write_raw,
0307     .attrs = &pa12203001_attr_group,
0308 };
0309 
0310 static int pa12203001_init(struct iio_dev *indio_dev)
0311 {
0312     struct pa12203001_data *data = iio_priv(indio_dev);
0313     int i, ret;
0314 
0315     for (i = 0; i < ARRAY_SIZE(regvals); i++) {
0316         ret = regmap_write(data->map, regvals[i].reg, regvals[i].val);
0317         if (ret < 0)
0318             return ret;
0319     }
0320 
0321     return 0;
0322 }
0323 
0324 static int pa12203001_power_chip(struct iio_dev *indio_dev, u8 state)
0325 {
0326     struct pa12203001_data *data = iio_priv(indio_dev);
0327     int ret;
0328 
0329     mutex_lock(&data->lock);
0330     ret = pa12203001_als_enable(data, state);
0331     if (ret < 0)
0332         goto out;
0333 
0334     ret = pa12203001_px_enable(data, state);
0335 
0336 out:
0337     mutex_unlock(&data->lock);
0338     return ret;
0339 }
0340 
0341 static int pa12203001_probe(struct i2c_client *client,
0342                 const struct i2c_device_id *id)
0343 {
0344     struct pa12203001_data *data;
0345     struct iio_dev *indio_dev;
0346     int ret;
0347 
0348     indio_dev = devm_iio_device_alloc(&client->dev,
0349                       sizeof(struct pa12203001_data));
0350     if (!indio_dev)
0351         return -ENOMEM;
0352 
0353     data = iio_priv(indio_dev);
0354     i2c_set_clientdata(client, indio_dev);
0355     data->client = client;
0356 
0357     data->map = devm_regmap_init_i2c(client, &pa12203001_regmap_config);
0358     if (IS_ERR(data->map))
0359         return PTR_ERR(data->map);
0360 
0361     mutex_init(&data->lock);
0362 
0363     indio_dev->info = &pa12203001_info;
0364     indio_dev->name = PA12203001_DRIVER_NAME;
0365     indio_dev->channels = pa12203001_channels;
0366     indio_dev->num_channels = ARRAY_SIZE(pa12203001_channels);
0367     indio_dev->modes = INDIO_DIRECT_MODE;
0368 
0369     ret = pa12203001_init(indio_dev);
0370     if (ret < 0)
0371         return ret;
0372 
0373     ret = pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
0374     if (ret < 0)
0375         return ret;
0376 
0377     ret = pm_runtime_set_active(&client->dev);
0378     if (ret < 0)
0379         goto out_err;
0380 
0381     pm_runtime_enable(&client->dev);
0382     pm_runtime_set_autosuspend_delay(&client->dev,
0383                      PA12203001_SLEEP_DELAY_MS);
0384     pm_runtime_use_autosuspend(&client->dev);
0385 
0386     ret = iio_device_register(indio_dev);
0387     if (ret < 0)
0388         goto out_err;
0389 
0390     return 0;
0391 
0392 out_err:
0393     pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
0394     return ret;
0395 }
0396 
0397 static int pa12203001_remove(struct i2c_client *client)
0398 {
0399     struct iio_dev *indio_dev = i2c_get_clientdata(client);
0400     int ret;
0401 
0402     iio_device_unregister(indio_dev);
0403 
0404     pm_runtime_disable(&client->dev);
0405     pm_runtime_set_suspended(&client->dev);
0406 
0407     ret = pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
0408     if (ret)
0409         dev_warn(&client->dev, "Failed to power down (%pe)\n",
0410              ERR_PTR(ret));
0411 
0412     return 0;
0413 }
0414 
0415 #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
0416 static int pa12203001_suspend(struct device *dev)
0417 {
0418     struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0419 
0420     return pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
0421 }
0422 #endif
0423 
0424 #ifdef CONFIG_PM_SLEEP
0425 static int pa12203001_resume(struct device *dev)
0426 {
0427     struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0428 
0429     return pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
0430 }
0431 #endif
0432 
0433 #ifdef CONFIG_PM
0434 static int pa12203001_runtime_resume(struct device *dev)
0435 {
0436     struct pa12203001_data *data;
0437 
0438     data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
0439 
0440     mutex_lock(&data->lock);
0441     if (data->als_needs_enable) {
0442         pa12203001_als_enable(data, PA12203001_ALS_EN_MASK);
0443         data->als_needs_enable = false;
0444     }
0445     if (data->px_needs_enable) {
0446         pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
0447         data->px_needs_enable = false;
0448     }
0449     mutex_unlock(&data->lock);
0450 
0451     return 0;
0452 }
0453 #endif
0454 
0455 static const struct dev_pm_ops pa12203001_pm_ops = {
0456     SET_SYSTEM_SLEEP_PM_OPS(pa12203001_suspend, pa12203001_resume)
0457     SET_RUNTIME_PM_OPS(pa12203001_suspend, pa12203001_runtime_resume, NULL)
0458 };
0459 
0460 static const struct acpi_device_id pa12203001_acpi_match[] = {
0461     { "TXCPA122", 0 },
0462     {}
0463 };
0464 
0465 MODULE_DEVICE_TABLE(acpi, pa12203001_acpi_match);
0466 
0467 static const struct i2c_device_id pa12203001_id[] = {
0468         { "txcpa122", 0 },
0469         {}
0470 };
0471 
0472 MODULE_DEVICE_TABLE(i2c, pa12203001_id);
0473 
0474 static struct i2c_driver pa12203001_driver = {
0475     .driver = {
0476         .name = PA12203001_DRIVER_NAME,
0477         .pm = &pa12203001_pm_ops,
0478         .acpi_match_table = ACPI_PTR(pa12203001_acpi_match),
0479     },
0480     .probe = pa12203001_probe,
0481     .remove = pa12203001_remove,
0482     .id_table = pa12203001_id,
0483 
0484 };
0485 module_i2c_driver(pa12203001_driver);
0486 
0487 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
0488 MODULE_DESCRIPTION("Driver for TXC PA12203001 Proximity and Light Sensor");
0489 MODULE_LICENSE("GPL v2");