Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/input/touchscreen/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  raspberrypi-ts.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Raspberry Pi firmware based touchscreen driver
 *
 * Copyright (C) 2015, 2017 Raspberry Pi
 * Copyright (C) 2018 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
 */


#include <linux/io.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <soc/bcm2835/raspberrypi-firmware.h>

#define RPI_TS_DEFAULT_WIDTH 800
#define RPI_TS_DEFAULT_HEIGHT 480

#define RPI_TS_MAX_SUPPORTED_POINTS 10

#define RPI_TS_FTS_TOUCH_DOWN  0
#define RPI_TS_FTS_TOUCH_CONTACT 2

#define RPI_TS_POLL_INTERVAL  17 /* 60fps */

#define RPI_TS_NPOINTS_REG_INVALIDATE 99

struct rpi_ts {
 struct platform_device *pdev;
 struct input_dev *input;
 struct touchscreen_properties prop;

 void __iomem *fw_regs_va;
 dma_addr_t fw_regs_phys;

 int known_ids;
};

struct rpi_ts_regs {
 u8 device_mode;
 u8 gesture_id;
 u8 num_points;
 struct rpi_ts_touch {
  u8 xh;
  u8 xl;
  u8 yh;
  u8 yl;
  u8 pressure; /* Not supported */
  u8 area;     /* Not supported */
 } point[RPI_TS_MAX_SUPPORTED_POINTS];
};

static void rpi_ts_poll(struct input_dev *input)
{
 struct rpi_ts *ts = input_get_drvdata(input);
 struct rpi_ts_regs regs;
 int modified_ids = 0;
 long released_ids;
 int event_type;
 int touchid;
 int x, y;
 int i;

 memcpy_fromio(®s, ts->fw_regs_va, sizeof(regs));
 /*
 * We poll the memory based register copy of the touchscreen chip using
 * the number of points register to know whether the copy has been
 * updated (we write 99 to the memory copy, the GPU will write between
 * 0 - 10 points)
 */

 iowrite8(RPI_TS_NPOINTS_REG_INVALIDATE,
   ts->fw_regs_va + offsetof(struct rpi_ts_regs, num_points));

 if (regs.num_points == RPI_TS_NPOINTS_REG_INVALIDATE ||
     (regs.num_points == 0 && ts->known_ids == 0))
  return;

 for (i = 0; i < regs.num_points; i++) {
  x = (((int)regs.point[i].xh & 0xf) << 8) + regs.point[i].xl;
  y = (((int)regs.point[i].yh & 0xf) << 8) + regs.point[i].yl;
  touchid = (regs.point[i].yh >> 4) & 0xf;
  event_type = (regs.point[i].xh >> 6) & 0x03;

  modified_ids |= BIT(touchid);

  if (event_type == RPI_TS_FTS_TOUCH_DOWN ||
      event_type == RPI_TS_FTS_TOUCH_CONTACT) {
   input_mt_slot(input, touchid);
   input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
   touchscreen_report_pos(input, &ts->prop, x, y, true);
  }
 }

 released_ids = ts->known_ids & ~modified_ids;
 for_each_set_bit(i, &released_ids, RPI_TS_MAX_SUPPORTED_POINTS) {
  input_mt_slot(input, i);
  input_mt_report_slot_inactive(input);
  modified_ids &= ~(BIT(i));
 }
 ts->known_ids = modified_ids;

 input_mt_sync_frame(input);
 input_sync(input);
}

static void rpi_ts_dma_cleanup(void *data)
{
 struct rpi_ts *ts = data;
 struct device *dev = &ts->pdev->dev;

 dma_free_coherent(dev, PAGE_SIZE, ts->fw_regs_va, ts->fw_regs_phys);
}

static int rpi_ts_probe(struct platform_device *pdev)
{
 struct device *dev = &pdev->dev;
 struct device_node *np = dev->of_node;
 struct input_dev *input;
 struct rpi_firmware *fw;
 struct rpi_ts *ts;
 u32 touchbuf;
 int error;

 struct device_node *fw_node __free(device_node) = of_get_parent(np);
 if (!fw_node) {
  dev_err(dev, "Missing firmware node\n");
  return -ENOENT;
 }

 fw = devm_rpi_firmware_get(&pdev->dev, fw_node);
 if (!fw)
  return -EPROBE_DEFER;

 ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
 if (!ts)
  return -ENOMEM;
 ts->pdev = pdev;

 ts->fw_regs_va = dma_alloc_coherent(dev, PAGE_SIZE, &ts->fw_regs_phys,
         GFP_KERNEL);
 if (!ts->fw_regs_va) {
  dev_err(dev, "failed to dma_alloc_coherent\n");
  return -ENOMEM;
 }

 error = devm_add_action_or_reset(dev, rpi_ts_dma_cleanup, ts);
 if (error) {
  dev_err(dev, "failed to devm_add_action_or_reset, %d\n", error);
  return error;
 }

 touchbuf = (u32)ts->fw_regs_phys;
 error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF,
          &touchbuf, sizeof(touchbuf));
 if (error || touchbuf != 0) {
  dev_warn(dev, "Failed to set touchbuf, %d\n", error);
  return error;
 }

 input = devm_input_allocate_device(dev);
 if (!input) {
  dev_err(dev, "Failed to allocate input device\n");
  return -ENOMEM;
 }

 ts->input = input;
 input_set_drvdata(input, ts);

 input->name = "raspberrypi-ts";
 input->id.bustype = BUS_HOST;

 input_set_abs_params(input, ABS_MT_POSITION_X, 0,
        RPI_TS_DEFAULT_WIDTH, 0, 0);
 input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
        RPI_TS_DEFAULT_HEIGHT, 0, 0);
 touchscreen_parse_properties(input, true, &ts->prop);

 error = input_mt_init_slots(input, RPI_TS_MAX_SUPPORTED_POINTS,
        INPUT_MT_DIRECT);
 if (error) {
  dev_err(dev, "could not init mt slots, %d\n", error);
  return error;
 }

 error = input_setup_polling(input, rpi_ts_poll);
 if (error) {
  dev_err(dev, "could not set up polling mode, %d\n", error);
  return error;
 }

 input_set_poll_interval(input, RPI_TS_POLL_INTERVAL);

 error = input_register_device(input);
 if (error) {
  dev_err(dev, "could not register input device, %d\n", error);
  return error;
 }

 return 0;
}

static const struct of_device_id rpi_ts_match[] = {
 { .compatible = "raspberrypi,firmware-ts", },
 {},
};
MODULE_DEVICE_TABLE(of, rpi_ts_match);

static struct platform_driver rpi_ts_driver = {
 .driver = {
  .name = "raspberrypi-ts",
  .of_match_table = rpi_ts_match,
 },
 .probe = rpi_ts_probe,
};
module_platform_driver(rpi_ts_driver);

MODULE_AUTHOR("Gordon Hollingworth");
MODULE_AUTHOR("Nicolas Saenz Julienne ");
MODULE_DESCRIPTION("Raspberry Pi firmware based touchscreen driver");
MODULE_LICENSE("GPL v2");

Messung V0.5
C=88 H=100 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.