<commit_before>//------------------------------------------------------------------------------
/// \file   sysfs_device.c
/// \brief  MXT device low level access via I2C
/// \author <NAME>
//------------------------------------------------------------------------------
// Copyright 2011 Atmel Corporation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
//
//    2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY ATMEL ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL ATMEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//------------------------------------------------------------------------------

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <malloc.h>
#include <stdio.h>

#include "libmaxtouch/log.h"
#include "libmaxtouch/info_block.h"
#include "dmesg.h"
#include "sysfs_device.h"

#define SYSFS_I2C_ROOT "/sys/bus/i2c/drivers/"
#define SYSFS_SPI_ROOT "/sys/bus/spi/drivers/"

//******************************************************************************
/// \brief Device information
typedef struct sysfs_device_t {
  int adapter;
  int address;
  char *path;
  char *mem_access_path;
  bool debug_ng;
  uint16_t debug_ng_msg_count;
  uint16_t debug_ng_msg_ptr;
  uint8_t *debug_ng_msg_buf;
  int debug_notify_fd;
  size_t debug_ng_size;
} sysfs_device;

/* detected devices */
sysfs_device *gpDevice = NULL;

/* char buffer for constructing paths */
#define PATH_LENGTH 256
char tempPath[PATH_LENGTH + 1];

//******************************************************************************
/// \brief Construct filename of path
static char *make_path(const char *filename)
{
  snprintf(tempPath, PATH_LENGTH, "%s/%s", gpDevice->path, filename);

  return &tempPath[0];
}

static void sysfs_open_notify_fd(void)
{
  char *filename = make_path("debug_notify");

  gpDevice->debug_notify_fd = open(filename, O_RDONLY);
  if (gpDevice->debug_notify_fd < 0) {
    LOG(LOG_ERROR, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    return;
  }
}

static void sysfs_reopen_notify_fd(void)
{
  uint16_t val;

  close(gpDevice->debug_notify_fd);
  sysfs_open_notify_fd();
  read(gpDevice->debug_notify_fd, &val, 2);
}

//******************************************************************************
/// \brief Register sysfs device
static void sysfs_register_device(const char *dirname, int adapter,
                                  int address, bool debug_ng)
{
  gpDevice = (sysfs_device *)calloc(1, sizeof(sysfs_device));
  gpDevice->path = (char *)calloc(strlen(dirname) + 1, sizeof(char));
  gpDevice->mem_access_path = (char *)calloc(strlen(dirname) + 20, sizeof(char));

  gpDevice->adapter = adapter;
  gpDevice->address = address;

  gpDevice->path[0] = '\0';
  memcpy(gpDevice->path, dirname, strlen(dirname) + 1);

  // Cache memory access path for fast access
  snprintf(gpDevice->mem_access_path, strlen(dirname) + 20,
           "%s/mem_access", dirname);

  if (debug_ng)
  {
    sysfs_open_notify_fd();
    gpDevice->debug_ng = true;
  }

  LOG(LOG_INFO, "Registered sysfs adapter:%d address:%x path:%s",
        gpDevice->adapter, gpDevice->address, gpDevice->path);
}

//******************************************************************************
/// \brief Check whether device has NG debug
bool sysfs_has_debug_ng()
{
  return gpDevice->debug_ng;
}

//******************************************************************************
/// \brief Get fd for select
int sysfs_get_debug_ng_fd()
{
  return gpDevice->debug_notify_fd;
}

//******************************************************************************
/// \brief Check sysfs device directory for correct files
/// \return 1 = device found, 0 = not found, negative for error
static int scan_sysfs_directory(struct dirent *i2c_dir,
                                const char *dirname, int adapter, int address)
{
  char *pszDirname;
  size_t length;
  DIR *pDirectory;
  struct dirent *pEntry;
  bool mem_access_found = false;
  bool debug_found = false;<commit_msg>Always set a value for gpDevice->debug_ng<commit_after>//------------------------------------------------------------------------------
/// \file   sysfs_device.c
/// \brief  MXT device low level access via I2C
/// \author <NAME>
//------------------------------------------------------------------------------
// Copyright 2011 Atmel Corporation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
//
//    2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY ATMEL ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL ATMEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//------------------------------------------------------------------------------

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <malloc.h>
#include <stdio.h>

#include "libmaxtouch/log.h"
#include "libmaxtouch/info_block.h"
#include "dmesg.h"
#include "sysfs_device.h"

#define SYSFS_I2C_ROOT "/sys/bus/i2c/drivers/"
#define SYSFS_SPI_ROOT "/sys/bus/spi/drivers/"

//******************************************************************************
/// \brief Device information
typedef struct sysfs_device_t {
  int adapter;
  int address;
  char *path;
  char *mem_access_path;
  bool debug_ng;
  uint16_t debug_ng_msg_count;
  uint16_t debug_ng_msg_ptr;
  uint8_t *debug_ng_msg_buf;
  int debug_notify_fd;
  size_t debug_ng_size;
} sysfs_device;

/* detected devices */
sysfs_device *gpDevice = NULL;

/* char buffer for constructing paths */
#define PATH_LENGTH 256
char tempPath[PATH_LENGTH + 1];

//******************************************************************************
/// \brief Construct filename of path
static char *make_path(const char *filename)
{
  snprintf(tempPath, PATH_LENGTH, "%s/%s", gpDevice->path, filename);

  return &tempPath[0];
}

static void sysfs_open_notify_fd(void)
{
  char *filename = make_path("debug_notify");

  gpDevice->debug_notify_fd = open(filename, O_RDONLY);
  if (gpDevice->debug_notify_fd < 0) {
    LOG(LOG_ERROR, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    return;
  }
}

static void sysfs_reopen_notify_fd(void)
{
  uint16_t val;

  close(gpDevice->debug_notify_fd);
  sysfs_open_notify_fd();
  read(gpDevice->debug_notify_fd, &val, 2);
}

//******************************************************************************
/// \brief Register sysfs device
static void sysfs_register_device(const char *dirname, int adapter,
                                  int address, bool debug_ng)
{
  gpDevice = (sysfs_device *)calloc(1, sizeof(sysfs_device));
  gpDevice->path = (char *)calloc(strlen(dirname) + 1, sizeof(char));
  gpDevice->mem_access_path = (char *)calloc(strlen(dirname) + 20, sizeof(char));

  gpDevice->adapter = adapter;
  gpDevice->address = address;

  gpDevice->path[0] = '\0';
  memcpy(gpDevice->path, dirname, strlen(dirname) + 1);

  // Cache memory access path for fast access
  snprintf(gpDevice->mem_access_path, strlen(dirname) + 20,
           "%s/mem_access", dirname);

  if (debug_ng)
  {
    sysfs_open_notify_fd();
    gpDevice->debug_ng = true;
  }
  else
  {
    gpDevice->debug_ng = false;
  }

  LOG(LOG_INFO, "Registered sysfs adapter:%d address:%x path:%s",
        gpDevice->adapter, gpDevice->address, gpDevice->path);
}

//******************************************************************************
/// \brief Check whether device has NG debug
bool sysfs_has_debug_ng()
{
  return gpDevice->debug_ng;
}

//******************************************************************************
/// \brief Get fd for select
int sysfs_get_debug_ng_fd()
{
  return gpDevice->debug_notify_fd;
}

//******************************************************************************
/// \brief Check sysfs device directory for correct files
/// \return 1 = device found, 0 = not found, negative for error
static int scan_sysfs_directory(struct dirent *i2c_dir,
                                const char *dirname, int adapter, int address)
{
  char *pszDirname;
  size_t length;
  DIR *pDirectory;
  struct dirent *pEntry;
  bool mem_access_found = false;
  bool debug_found = false;
{'fraction_non_alphanumeric': 0.2324153152288648, 'fraction_numerical': 0.00671720564245274, 'mean_word_length': 3.4348936170212765, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4722652', 'n_tokens_mistral': 3126, 'n_tokens_neox': 2889, 'n_words': 921}