0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/device.h>
0013 #include <linux/iio/sysfs.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/irqreturn.h>
0018 #include <linux/iio/trigger.h>
0019 #include <linux/iio/trigger_consumer.h>
0020 #include <linux/iio/triggered_buffer.h>
0021 #include <linux/iio/buffer.h>
0022 #include <linux/regmap.h>
0023
0024 #include "st_uvis25.h"
0025
0026 #define ST_UVIS25_REG_WHOAMI_ADDR 0x0f
0027 #define ST_UVIS25_REG_WHOAMI_VAL 0xca
0028 #define ST_UVIS25_REG_CTRL1_ADDR 0x20
0029 #define ST_UVIS25_REG_ODR_MASK BIT(0)
0030 #define ST_UVIS25_REG_BDU_MASK BIT(1)
0031 #define ST_UVIS25_REG_CTRL2_ADDR 0x21
0032 #define ST_UVIS25_REG_BOOT_MASK BIT(7)
0033 #define ST_UVIS25_REG_CTRL3_ADDR 0x22
0034 #define ST_UVIS25_REG_HL_MASK BIT(7)
0035 #define ST_UVIS25_REG_STATUS_ADDR 0x27
0036 #define ST_UVIS25_REG_UV_DA_MASK BIT(0)
0037 #define ST_UVIS25_REG_OUT_ADDR 0x28
0038
0039 static const struct iio_chan_spec st_uvis25_channels[] = {
0040 {
0041 .type = IIO_UVINDEX,
0042 .address = ST_UVIS25_REG_OUT_ADDR,
0043 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0044 .scan_index = 0,
0045 .scan_type = {
0046 .sign = 'u',
0047 .realbits = 8,
0048 .storagebits = 8,
0049 },
0050 },
0051 IIO_CHAN_SOFT_TIMESTAMP(1),
0052 };
0053
0054 static int st_uvis25_check_whoami(struct st_uvis25_hw *hw)
0055 {
0056 int err, data;
0057
0058 err = regmap_read(hw->regmap, ST_UVIS25_REG_WHOAMI_ADDR, &data);
0059 if (err < 0) {
0060 dev_err(regmap_get_device(hw->regmap),
0061 "failed to read whoami register\n");
0062 return err;
0063 }
0064
0065 if (data != ST_UVIS25_REG_WHOAMI_VAL) {
0066 dev_err(regmap_get_device(hw->regmap),
0067 "wrong whoami {%02x vs %02x}\n",
0068 data, ST_UVIS25_REG_WHOAMI_VAL);
0069 return -ENODEV;
0070 }
0071
0072 return 0;
0073 }
0074
0075 static int st_uvis25_set_enable(struct st_uvis25_hw *hw, bool enable)
0076 {
0077 int err;
0078
0079 err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
0080 ST_UVIS25_REG_ODR_MASK, enable);
0081 if (err < 0)
0082 return err;
0083
0084 hw->enabled = enable;
0085
0086 return 0;
0087 }
0088
0089 static int st_uvis25_read_oneshot(struct st_uvis25_hw *hw, u8 addr, int *val)
0090 {
0091 int err;
0092
0093 err = st_uvis25_set_enable(hw, true);
0094 if (err < 0)
0095 return err;
0096
0097 msleep(1500);
0098
0099
0100
0101
0102
0103
0104
0105 err = st_uvis25_set_enable(hw, false);
0106 if (err < 0)
0107 return err;
0108
0109 err = regmap_read(hw->regmap, addr, val);
0110
0111 return err < 0 ? err : IIO_VAL_INT;
0112 }
0113
0114 static int st_uvis25_read_raw(struct iio_dev *iio_dev,
0115 struct iio_chan_spec const *ch,
0116 int *val, int *val2, long mask)
0117 {
0118 int ret;
0119
0120 ret = iio_device_claim_direct_mode(iio_dev);
0121 if (ret)
0122 return ret;
0123
0124 switch (mask) {
0125 case IIO_CHAN_INFO_PROCESSED: {
0126 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0127
0128
0129
0130
0131
0132
0133
0134
0135 if (hw->irq > 0)
0136 disable_irq(hw->irq);
0137 ret = st_uvis25_read_oneshot(hw, ch->address, val);
0138 if (hw->irq > 0)
0139 enable_irq(hw->irq);
0140 break;
0141 }
0142 default:
0143 ret = -EINVAL;
0144 break;
0145 }
0146
0147 iio_device_release_direct_mode(iio_dev);
0148
0149 return ret;
0150 }
0151
0152 static irqreturn_t st_uvis25_trigger_handler_thread(int irq, void *private)
0153 {
0154 struct st_uvis25_hw *hw = private;
0155 int err, status;
0156
0157 err = regmap_read(hw->regmap, ST_UVIS25_REG_STATUS_ADDR, &status);
0158 if (err < 0)
0159 return IRQ_HANDLED;
0160
0161 if (!(status & ST_UVIS25_REG_UV_DA_MASK))
0162 return IRQ_NONE;
0163
0164 iio_trigger_poll_chained(hw->trig);
0165
0166 return IRQ_HANDLED;
0167 }
0168
0169 static int st_uvis25_allocate_trigger(struct iio_dev *iio_dev)
0170 {
0171 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0172 struct device *dev = regmap_get_device(hw->regmap);
0173 bool irq_active_low = false;
0174 unsigned long irq_type;
0175 int err;
0176
0177 irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
0178
0179 switch (irq_type) {
0180 case IRQF_TRIGGER_HIGH:
0181 case IRQF_TRIGGER_RISING:
0182 break;
0183 case IRQF_TRIGGER_LOW:
0184 case IRQF_TRIGGER_FALLING:
0185 irq_active_low = true;
0186 break;
0187 default:
0188 dev_info(dev, "mode %lx unsupported\n", irq_type);
0189 return -EINVAL;
0190 }
0191
0192 err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL3_ADDR,
0193 ST_UVIS25_REG_HL_MASK, irq_active_low);
0194 if (err < 0)
0195 return err;
0196
0197 err = devm_request_threaded_irq(dev, hw->irq, NULL,
0198 st_uvis25_trigger_handler_thread,
0199 irq_type | IRQF_ONESHOT,
0200 iio_dev->name, hw);
0201 if (err) {
0202 dev_err(dev, "failed to request trigger irq %d\n",
0203 hw->irq);
0204 return err;
0205 }
0206
0207 hw->trig = devm_iio_trigger_alloc(dev, "%s-trigger",
0208 iio_dev->name);
0209 if (!hw->trig)
0210 return -ENOMEM;
0211
0212 iio_trigger_set_drvdata(hw->trig, iio_dev);
0213
0214 return devm_iio_trigger_register(dev, hw->trig);
0215 }
0216
0217 static int st_uvis25_buffer_preenable(struct iio_dev *iio_dev)
0218 {
0219 return st_uvis25_set_enable(iio_priv(iio_dev), true);
0220 }
0221
0222 static int st_uvis25_buffer_postdisable(struct iio_dev *iio_dev)
0223 {
0224 return st_uvis25_set_enable(iio_priv(iio_dev), false);
0225 }
0226
0227 static const struct iio_buffer_setup_ops st_uvis25_buffer_ops = {
0228 .preenable = st_uvis25_buffer_preenable,
0229 .postdisable = st_uvis25_buffer_postdisable,
0230 };
0231
0232 static irqreturn_t st_uvis25_buffer_handler_thread(int irq, void *p)
0233 {
0234 struct iio_poll_func *pf = p;
0235 struct iio_dev *iio_dev = pf->indio_dev;
0236 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0237 unsigned int val;
0238 int err;
0239
0240 err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, &val);
0241 if (err < 0)
0242 goto out;
0243
0244 hw->scan.chan = val;
0245
0246 iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
0247 iio_get_time_ns(iio_dev));
0248
0249 out:
0250 iio_trigger_notify_done(hw->trig);
0251
0252 return IRQ_HANDLED;
0253 }
0254
0255 static int st_uvis25_allocate_buffer(struct iio_dev *iio_dev)
0256 {
0257 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0258
0259 return devm_iio_triggered_buffer_setup(regmap_get_device(hw->regmap),
0260 iio_dev, NULL,
0261 st_uvis25_buffer_handler_thread,
0262 &st_uvis25_buffer_ops);
0263 }
0264
0265 static const struct iio_info st_uvis25_info = {
0266 .read_raw = st_uvis25_read_raw,
0267 };
0268
0269 static int st_uvis25_init_sensor(struct st_uvis25_hw *hw)
0270 {
0271 int err;
0272
0273 err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL2_ADDR,
0274 ST_UVIS25_REG_BOOT_MASK, 1);
0275 if (err < 0)
0276 return err;
0277
0278 msleep(2000);
0279
0280 return regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
0281 ST_UVIS25_REG_BDU_MASK, 1);
0282 }
0283
0284 int st_uvis25_probe(struct device *dev, int irq, struct regmap *regmap)
0285 {
0286 struct st_uvis25_hw *hw;
0287 struct iio_dev *iio_dev;
0288 int err;
0289
0290 iio_dev = devm_iio_device_alloc(dev, sizeof(*hw));
0291 if (!iio_dev)
0292 return -ENOMEM;
0293
0294 dev_set_drvdata(dev, (void *)iio_dev);
0295
0296 hw = iio_priv(iio_dev);
0297 hw->irq = irq;
0298 hw->regmap = regmap;
0299
0300 err = st_uvis25_check_whoami(hw);
0301 if (err < 0)
0302 return err;
0303
0304 iio_dev->modes = INDIO_DIRECT_MODE;
0305 iio_dev->channels = st_uvis25_channels;
0306 iio_dev->num_channels = ARRAY_SIZE(st_uvis25_channels);
0307 iio_dev->name = ST_UVIS25_DEV_NAME;
0308 iio_dev->info = &st_uvis25_info;
0309
0310 err = st_uvis25_init_sensor(hw);
0311 if (err < 0)
0312 return err;
0313
0314 if (hw->irq > 0) {
0315 err = st_uvis25_allocate_buffer(iio_dev);
0316 if (err < 0)
0317 return err;
0318
0319 err = st_uvis25_allocate_trigger(iio_dev);
0320 if (err)
0321 return err;
0322 }
0323
0324 return devm_iio_device_register(dev, iio_dev);
0325 }
0326 EXPORT_SYMBOL_NS(st_uvis25_probe, IIO_UVIS25);
0327
0328 static int __maybe_unused st_uvis25_suspend(struct device *dev)
0329 {
0330 struct iio_dev *iio_dev = dev_get_drvdata(dev);
0331 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0332
0333 return regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
0334 ST_UVIS25_REG_ODR_MASK, 0);
0335 }
0336
0337 static int __maybe_unused st_uvis25_resume(struct device *dev)
0338 {
0339 struct iio_dev *iio_dev = dev_get_drvdata(dev);
0340 struct st_uvis25_hw *hw = iio_priv(iio_dev);
0341
0342 if (hw->enabled)
0343 return regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
0344 ST_UVIS25_REG_ODR_MASK, 1);
0345
0346 return 0;
0347 }
0348
0349 const struct dev_pm_ops st_uvis25_pm_ops = {
0350 SET_SYSTEM_SLEEP_PM_OPS(st_uvis25_suspend, st_uvis25_resume)
0351 };
0352 EXPORT_SYMBOL_NS(st_uvis25_pm_ops, IIO_UVIS25);
0353
0354 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
0355 MODULE_DESCRIPTION("STMicroelectronics uvis25 sensor driver");
0356 MODULE_LICENSE("GPL v2");