Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * ADC generic resistive touchscreen (GRTS)
0004  * This is a generic input driver that connects to an ADC
0005  * given the channels in device tree, and reports events to the input
0006  * subsystem.
0007  *
0008  * Copyright (C) 2017,2018 Microchip Technology,
0009  * Author: Eugen Hristev <eugen.hristev@microchip.com>
0010  *
0011  */
0012 #include <linux/input.h>
0013 #include <linux/input/touchscreen.h>
0014 #include <linux/iio/consumer.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/mod_devicetable.h>
0017 #include <linux/module.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/property.h>
0020 
0021 #define DRIVER_NAME                 "resistive-adc-touch"
0022 #define GRTS_DEFAULT_PRESSURE_MIN           50000
0023 #define GRTS_DEFAULT_PRESSURE_MAX           65535
0024 #define GRTS_MAX_POS_MASK               GENMASK(11, 0)
0025 #define GRTS_MAX_CHANNELS               4
0026 
0027 enum grts_ch_type {
0028     GRTS_CH_X,
0029     GRTS_CH_Y,
0030     GRTS_CH_PRESSURE,
0031     GRTS_CH_Z1,
0032     GRTS_CH_Z2,
0033     GRTS_CH_MAX = GRTS_CH_Z2 + 1
0034 };
0035 
0036 /**
0037  * struct grts_state - generic resistive touch screen information struct
0038  * @x_plate_ohms:   resistance of the X plate
0039  * @pressure_min:   number representing the minimum for the pressure
0040  * @pressure:       are we getting pressure info or not
0041  * @iio_chans:      list of channels acquired
0042  * @iio_cb:     iio_callback buffer for the data
0043  * @input:      the input device structure that we register
0044  * @prop:       touchscreen properties struct
0045  * @ch_map:     map of channels that are defined for the touchscreen
0046  */
0047 struct grts_state {
0048     u32             x_plate_ohms;
0049     u32             pressure_min;
0050     bool                pressure;
0051     struct iio_channel      *iio_chans;
0052     struct iio_cb_buffer        *iio_cb;
0053     struct input_dev        *input;
0054     struct touchscreen_properties   prop;
0055     u8              ch_map[GRTS_CH_MAX];
0056 };
0057 
0058 static int grts_cb(const void *data, void *private)
0059 {
0060     const u16 *touch_info = data;
0061     struct grts_state *st = private;
0062     unsigned int x, y, press = 0;
0063 
0064     x = touch_info[st->ch_map[GRTS_CH_X]];
0065     y = touch_info[st->ch_map[GRTS_CH_Y]];
0066 
0067     if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
0068         press = touch_info[st->ch_map[GRTS_CH_PRESSURE]];
0069     } else if (st->ch_map[GRTS_CH_Z1] < GRTS_MAX_CHANNELS) {
0070         unsigned int z1 = touch_info[st->ch_map[GRTS_CH_Z1]];
0071         unsigned int z2 = touch_info[st->ch_map[GRTS_CH_Z2]];
0072         unsigned int Rt;
0073 
0074         if (likely(x && z1)) {
0075             Rt = z2;
0076             Rt -= z1;
0077             Rt *= st->x_plate_ohms;
0078             Rt = DIV_ROUND_CLOSEST(Rt, 16);
0079             Rt *= x;
0080             Rt /= z1;
0081             Rt = DIV_ROUND_CLOSEST(Rt, 256);
0082             /*
0083              * On increased pressure the resistance (Rt) is
0084              * decreasing so, convert values to make it looks as
0085              * real pressure.
0086              */
0087             if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
0088                 press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
0089         }
0090     }
0091 
0092     if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
0093         /* report end of touch */
0094         input_report_key(st->input, BTN_TOUCH, 0);
0095         input_sync(st->input);
0096         return 0;
0097     }
0098 
0099     /* report proper touch to subsystem*/
0100     touchscreen_report_pos(st->input, &st->prop, x, y, false);
0101     if (st->pressure)
0102         input_report_abs(st->input, ABS_PRESSURE, press);
0103     input_report_key(st->input, BTN_TOUCH, 1);
0104     input_sync(st->input);
0105 
0106     return 0;
0107 }
0108 
0109 static int grts_open(struct input_dev *dev)
0110 {
0111     int error;
0112     struct grts_state *st = input_get_drvdata(dev);
0113 
0114     error = iio_channel_start_all_cb(st->iio_cb);
0115     if (error) {
0116         dev_err(dev->dev.parent, "failed to start callback buffer.\n");
0117         return error;
0118     }
0119     return 0;
0120 }
0121 
0122 static void grts_close(struct input_dev *dev)
0123 {
0124     struct grts_state *st = input_get_drvdata(dev);
0125 
0126     iio_channel_stop_all_cb(st->iio_cb);
0127 }
0128 
0129 static void grts_disable(void *data)
0130 {
0131     iio_channel_release_all_cb(data);
0132 }
0133 
0134 static int grts_map_channel(struct grts_state *st, struct device *dev,
0135                 enum grts_ch_type type, const char *name,
0136                 bool optional)
0137 {
0138     int idx;
0139 
0140     idx = device_property_match_string(dev, "io-channel-names", name);
0141     if (idx < 0) {
0142         if (!optional)
0143             return idx;
0144         idx = GRTS_MAX_CHANNELS;
0145     } else if (idx >= GRTS_MAX_CHANNELS) {
0146         return -EOVERFLOW;
0147     }
0148 
0149     st->ch_map[type] = idx;
0150     return 0;
0151 }
0152 
0153 static int grts_get_properties(struct grts_state *st, struct device *dev)
0154 {
0155     int error;
0156 
0157     error = grts_map_channel(st, dev, GRTS_CH_X, "x", false);
0158     if (error)
0159         return error;
0160 
0161     error = grts_map_channel(st, dev, GRTS_CH_Y, "y", false);
0162     if (error)
0163         return error;
0164 
0165     /* pressure is optional */
0166     error = grts_map_channel(st, dev, GRTS_CH_PRESSURE, "pressure", true);
0167     if (error)
0168         return error;
0169 
0170     if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
0171         st->pressure = true;
0172         return 0;
0173     }
0174 
0175     /* if no pressure is defined, try optional z1 + z2 */
0176     error = grts_map_channel(st, dev, GRTS_CH_Z1, "z1", true);
0177     if (error)
0178         return error;
0179 
0180     if (st->ch_map[GRTS_CH_Z1] >= GRTS_MAX_CHANNELS)
0181         return 0;
0182 
0183     /* if z1 is provided z2 is not optional */
0184     error = grts_map_channel(st, dev, GRTS_CH_Z2, "z2", true);
0185     if (error)
0186         return error;
0187 
0188     error = device_property_read_u32(dev,
0189                      "touchscreen-x-plate-ohms",
0190                      &st->x_plate_ohms);
0191     if (error) {
0192         dev_err(dev, "can't get touchscreen-x-plate-ohms property\n");
0193         return error;
0194     }
0195 
0196     st->pressure = true;
0197     return 0;
0198 }
0199 
0200 static int grts_probe(struct platform_device *pdev)
0201 {
0202     struct grts_state *st;
0203     struct input_dev *input;
0204     struct device *dev = &pdev->dev;
0205     int error;
0206 
0207     st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL);
0208     if (!st)
0209         return -ENOMEM;
0210 
0211     /* get the channels from IIO device */
0212     st->iio_chans = devm_iio_channel_get_all(dev);
0213     if (IS_ERR(st->iio_chans)) {
0214         error = PTR_ERR(st->iio_chans);
0215         if (error != -EPROBE_DEFER)
0216             dev_err(dev, "can't get iio channels.\n");
0217         return error;
0218     }
0219 
0220     if (!device_property_present(dev, "io-channel-names"))
0221         return -ENODEV;
0222 
0223     error = grts_get_properties(st, dev);
0224     if (error) {
0225         dev_err(dev, "Failed to parse properties\n");
0226         return error;
0227     }
0228 
0229     if (st->pressure) {
0230         error = device_property_read_u32(dev,
0231                          "touchscreen-min-pressure",
0232                          &st->pressure_min);
0233         if (error) {
0234             dev_dbg(dev, "can't get touchscreen-min-pressure property.\n");
0235             st->pressure_min = GRTS_DEFAULT_PRESSURE_MIN;
0236         }
0237     }
0238 
0239     input = devm_input_allocate_device(dev);
0240     if (!input) {
0241         dev_err(dev, "failed to allocate input device.\n");
0242         return -ENOMEM;
0243     }
0244 
0245     input->name = DRIVER_NAME;
0246     input->id.bustype = BUS_HOST;
0247     input->open = grts_open;
0248     input->close = grts_close;
0249 
0250     input_set_abs_params(input, ABS_X, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
0251     input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
0252     if (st->pressure)
0253         input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
0254                      GRTS_DEFAULT_PRESSURE_MAX, 0, 0);
0255 
0256     input_set_capability(input, EV_KEY, BTN_TOUCH);
0257 
0258     /* parse optional device tree properties */
0259     touchscreen_parse_properties(input, false, &st->prop);
0260 
0261     st->input = input;
0262     input_set_drvdata(input, st);
0263 
0264     error = input_register_device(input);
0265     if (error) {
0266         dev_err(dev, "failed to register input device.");
0267         return error;
0268     }
0269 
0270     st->iio_cb = iio_channel_get_all_cb(dev, grts_cb, st);
0271     if (IS_ERR(st->iio_cb)) {
0272         dev_err(dev, "failed to allocate callback buffer.\n");
0273         return PTR_ERR(st->iio_cb);
0274     }
0275 
0276     error = devm_add_action_or_reset(dev, grts_disable, st->iio_cb);
0277     if (error) {
0278         dev_err(dev, "failed to add disable action.\n");
0279         return error;
0280     }
0281 
0282     return 0;
0283 }
0284 
0285 static const struct of_device_id grts_of_match[] = {
0286     {
0287         .compatible = "resistive-adc-touch",
0288     }, {
0289         /* sentinel */
0290     },
0291 };
0292 
0293 MODULE_DEVICE_TABLE(of, grts_of_match);
0294 
0295 static struct platform_driver grts_driver = {
0296     .probe = grts_probe,
0297     .driver = {
0298         .name = DRIVER_NAME,
0299         .of_match_table = grts_of_match,
0300     },
0301 };
0302 
0303 module_platform_driver(grts_driver);
0304 
0305 MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>");
0306 MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver");
0307 MODULE_LICENSE("GPL v2");