0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <linux/err.h>
0030 #include <linux/gpio/consumer.h>
0031 #include <linux/kernel.h>
0032 #include <linux/mod_devicetable.h>
0033 #include <linux/module.h>
0034 #include <linux/platform_device.h>
0035 #include <linux/property.h>
0036 #include <linux/sched.h>
0037 #include <linux/interrupt.h>
0038 #include <linux/delay.h>
0039 #include <linux/iio/iio.h>
0040 #include <linux/iio/sysfs.h>
0041
0042 struct ping_cfg {
0043 unsigned long trigger_pulse_us;
0044 int laserping_error;
0045
0046
0047 s64 timeout_ns;
0048 };
0049
0050 struct ping_data {
0051 struct device *dev;
0052 struct gpio_desc *gpiod_ping;
0053 struct mutex lock;
0054 int irqnr;
0055 ktime_t ts_rising;
0056 ktime_t ts_falling;
0057 struct completion rising;
0058 struct completion falling;
0059 const struct ping_cfg *cfg;
0060 };
0061
0062 static const struct ping_cfg pa_ping_cfg = {
0063 .trigger_pulse_us = 5,
0064 .laserping_error = 0,
0065 .timeout_ns = 18500000,
0066 };
0067
0068 static const struct ping_cfg pa_laser_ping_cfg = {
0069 .trigger_pulse_us = 5,
0070 .laserping_error = 1,
0071 .timeout_ns = 15500000,
0072 };
0073
0074 static irqreturn_t ping_handle_irq(int irq, void *dev_id)
0075 {
0076 struct iio_dev *indio_dev = dev_id;
0077 struct ping_data *data = iio_priv(indio_dev);
0078 ktime_t now = ktime_get();
0079
0080 if (gpiod_get_value(data->gpiod_ping)) {
0081 data->ts_rising = now;
0082 complete(&data->rising);
0083 } else {
0084 data->ts_falling = now;
0085 complete(&data->falling);
0086 }
0087
0088 return IRQ_HANDLED;
0089 }
0090
0091 static int ping_read(struct iio_dev *indio_dev)
0092 {
0093 struct ping_data *data = iio_priv(indio_dev);
0094 int ret;
0095 ktime_t ktime_dt;
0096 s64 dt_ns;
0097 u32 time_ns, distance_mm;
0098 struct platform_device *pdev = to_platform_device(data->dev);
0099
0100
0101
0102
0103
0104 mutex_lock(&data->lock);
0105
0106 reinit_completion(&data->rising);
0107 reinit_completion(&data->falling);
0108
0109 gpiod_set_value(data->gpiod_ping, 1);
0110 udelay(data->cfg->trigger_pulse_us);
0111 gpiod_set_value(data->gpiod_ping, 0);
0112
0113 ret = gpiod_direction_input(data->gpiod_ping);
0114 if (ret < 0) {
0115 mutex_unlock(&data->lock);
0116 return ret;
0117 }
0118
0119 data->irqnr = gpiod_to_irq(data->gpiod_ping);
0120 if (data->irqnr < 0) {
0121 dev_err(data->dev, "gpiod_to_irq: %d\n", data->irqnr);
0122 mutex_unlock(&data->lock);
0123 return data->irqnr;
0124 }
0125
0126 ret = request_irq(data->irqnr, ping_handle_irq,
0127 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
0128 pdev->name, indio_dev);
0129 if (ret < 0) {
0130 dev_err(data->dev, "request_irq: %d\n", ret);
0131 mutex_unlock(&data->lock);
0132 return ret;
0133 }
0134
0135
0136 ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
0137 if (ret < 0)
0138 goto err_reset_direction;
0139 else if (ret == 0) {
0140 ret = -ETIMEDOUT;
0141 goto err_reset_direction;
0142 }
0143
0144
0145 ret = wait_for_completion_killable_timeout(&data->falling, HZ/20);
0146 if (ret < 0)
0147 goto err_reset_direction;
0148 else if (ret == 0) {
0149 ret = -ETIMEDOUT;
0150 goto err_reset_direction;
0151 }
0152
0153 ktime_dt = ktime_sub(data->ts_falling, data->ts_rising);
0154
0155 free_irq(data->irqnr, indio_dev);
0156
0157 ret = gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW);
0158 if (ret < 0) {
0159 mutex_unlock(&data->lock);
0160 return ret;
0161 }
0162
0163 mutex_unlock(&data->lock);
0164
0165 dt_ns = ktime_to_ns(ktime_dt);
0166 if (dt_ns > data->cfg->timeout_ns) {
0167 dev_dbg(data->dev, "distance out of range: dt=%lldns\n",
0168 dt_ns);
0169 return -EIO;
0170 }
0171
0172 time_ns = dt_ns;
0173
0174
0175
0176
0177
0178 if (data->cfg->laserping_error) {
0179 if ((time_ns > 12500000) && (time_ns <= 13500000)) {
0180 dev_dbg(data->dev, "target too close or to far\n");
0181 return -EIO;
0182 }
0183 if ((time_ns > 13500000) && (time_ns <= 14500000)) {
0184 dev_dbg(data->dev, "internal sensor error\n");
0185 return -EIO;
0186 }
0187 if ((time_ns > 14500000) && (time_ns <= 15500000)) {
0188 dev_dbg(data->dev, "internal sensor timeout\n");
0189 return -EIO;
0190 }
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 distance_mm = time_ns * 232 / 1350800;
0214
0215 return distance_mm;
0216
0217 err_reset_direction:
0218 free_irq(data->irqnr, indio_dev);
0219 mutex_unlock(&data->lock);
0220
0221 if (gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW))
0222 dev_dbg(data->dev, "error in gpiod_direction_output\n");
0223 return ret;
0224 }
0225
0226 static int ping_read_raw(struct iio_dev *indio_dev,
0227 struct iio_chan_spec const *channel, int *val,
0228 int *val2, long info)
0229 {
0230 int ret;
0231
0232 if (channel->type != IIO_DISTANCE)
0233 return -EINVAL;
0234
0235 switch (info) {
0236 case IIO_CHAN_INFO_RAW:
0237 ret = ping_read(indio_dev);
0238 if (ret < 0)
0239 return ret;
0240 *val = ret;
0241 return IIO_VAL_INT;
0242 case IIO_CHAN_INFO_SCALE:
0243
0244
0245
0246
0247 *val = 0;
0248 *val2 = 1000;
0249 return IIO_VAL_INT_PLUS_MICRO;
0250 default:
0251 return -EINVAL;
0252 }
0253 }
0254
0255 static const struct iio_info ping_iio_info = {
0256 .read_raw = ping_read_raw,
0257 };
0258
0259 static const struct iio_chan_spec ping_chan_spec[] = {
0260 {
0261 .type = IIO_DISTANCE,
0262 .info_mask_separate =
0263 BIT(IIO_CHAN_INFO_RAW) |
0264 BIT(IIO_CHAN_INFO_SCALE),
0265 },
0266 };
0267
0268 static const struct of_device_id of_ping_match[] = {
0269 { .compatible = "parallax,ping", .data = &pa_ping_cfg },
0270 { .compatible = "parallax,laserping", .data = &pa_laser_ping_cfg },
0271 {},
0272 };
0273
0274 MODULE_DEVICE_TABLE(of, of_ping_match);
0275
0276 static int ping_probe(struct platform_device *pdev)
0277 {
0278 struct device *dev = &pdev->dev;
0279 struct ping_data *data;
0280 struct iio_dev *indio_dev;
0281
0282 indio_dev = devm_iio_device_alloc(dev, sizeof(struct ping_data));
0283 if (!indio_dev) {
0284 dev_err(dev, "failed to allocate IIO device\n");
0285 return -ENOMEM;
0286 }
0287
0288 data = iio_priv(indio_dev);
0289 data->dev = dev;
0290 data->cfg = device_get_match_data(dev);
0291
0292 mutex_init(&data->lock);
0293 init_completion(&data->rising);
0294 init_completion(&data->falling);
0295
0296 data->gpiod_ping = devm_gpiod_get(dev, "ping", GPIOD_OUT_LOW);
0297 if (IS_ERR(data->gpiod_ping)) {
0298 dev_err(dev, "failed to get ping-gpios: err=%ld\n",
0299 PTR_ERR(data->gpiod_ping));
0300 return PTR_ERR(data->gpiod_ping);
0301 }
0302
0303 if (gpiod_cansleep(data->gpiod_ping)) {
0304 dev_err(data->dev, "cansleep-GPIOs not supported\n");
0305 return -ENODEV;
0306 }
0307
0308 platform_set_drvdata(pdev, indio_dev);
0309
0310 indio_dev->name = "ping";
0311 indio_dev->info = &ping_iio_info;
0312 indio_dev->modes = INDIO_DIRECT_MODE;
0313 indio_dev->channels = ping_chan_spec;
0314 indio_dev->num_channels = ARRAY_SIZE(ping_chan_spec);
0315
0316 return devm_iio_device_register(dev, indio_dev);
0317 }
0318
0319 static struct platform_driver ping_driver = {
0320 .probe = ping_probe,
0321 .driver = {
0322 .name = "ping-gpio",
0323 .of_match_table = of_ping_match,
0324 },
0325 };
0326
0327 module_platform_driver(ping_driver);
0328
0329 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
0330 MODULE_DESCRIPTION("PING sensors for distance measuring using one GPIOs");
0331 MODULE_LICENSE("GPL");
0332 MODULE_ALIAS("platform:ping");