From 5e4680f4ef37ebfffda9574549c879dbbc0ef02f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michael=20B=C3=BCsch?= Date: Wed, 6 Oct 2010 19:19:37 +0000 Subject: [PATCH] Add retutahvo tool. SVN-Revision: 23276 --- utils/retutahvo/Makefile | 41 +++ utils/retutahvo/files/src/Makefile | 4 + utils/retutahvo/files/src/retutahvo.c | 270 ++++++++++++++++++++ utils/retutahvo/files/src/user_retu_tahvo.h | 75 ++++++ 4 files changed, 390 insertions(+) create mode 100644 utils/retutahvo/Makefile create mode 100644 utils/retutahvo/files/src/Makefile create mode 100644 utils/retutahvo/files/src/retutahvo.c create mode 100644 utils/retutahvo/files/src/user_retu_tahvo.h diff --git a/utils/retutahvo/Makefile b/utils/retutahvo/Makefile new file mode 100644 index 0000000000..a620035ebe --- /dev/null +++ b/utils/retutahvo/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=retutahvo +PKG_RELEASE:=1 + +PKG_SOURCE_SUBDIR:=$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/retutahvo + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Retu/Tahvo userspace tool + DEPENDS:=+TARGET_omap24xx + MAINTAINER:=Michael Buesch +endef + +define Package/retutahvo/description + Nokia n810 Retu/Tahvo userspace tool. + Warning: Do not use this, if you don't know what you're doing. + This tool can physically damage the n810. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./files/src/* $(PKG_BUILD_DIR)/ +endef + +define Package/retutahvo/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/retutahvo $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,retutahvo)) diff --git a/utils/retutahvo/files/src/Makefile b/utils/retutahvo/files/src/Makefile new file mode 100644 index 0000000000..a4d7ea1f76 --- /dev/null +++ b/utils/retutahvo/files/src/Makefile @@ -0,0 +1,4 @@ +CC ?= gcc +CFLAGS ?= -O2 + +all: retutahvo diff --git a/utils/retutahvo/files/src/retutahvo.c b/utils/retutahvo/files/src/retutahvo.c new file mode 100644 index 0000000000..3f59d59e3b --- /dev/null +++ b/utils/retutahvo/files/src/retutahvo.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2010 Michael Buesch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +#include "user_retu_tahvo.h" + + +static const char * chip2str(int chip) +{ + switch (chip) { + case CHIP_RETU: + return "Retu"; + case CHIP_TAHVO: + return "Tahvo"; + } + return "UNKNOWN"; +} + +static int str2uint(const char *str, unsigned int *value) +{ + char *tail; + + *value = strtoul(str, &tail, 0); + if (*tail != '\0') + return -1; + + return 0; +} + +static int open_dev(int chip) +{ + const char *path; + int fd; + + switch (chip) { + case CHIP_RETU: + path = "/dev/retu"; + break; + case CHIP_TAHVO: + path = "/dev/tahvo"; + break; + default: + return -1; + } + + fd = open(path, O_RDWR); + if (fd < 0) { + fprintf(stderr, "Failed to open %d: %s\n", + path, strerror(errno)); + } + + return fd; +} + +#define MASKREG(mask, reg) ((mask) | (((reg) & 0x3F) << 16)) + +static unsigned int encrapify_value(unsigned int value, unsigned int mask) +{ + if (!mask) + return 0; + while (!(mask & 1)) { + value >>= 1; + mask >>= 1; + } + + return value; +} + +static unsigned int decrapify_value(unsigned int value, unsigned int mask) +{ + if (!mask) + return 0; + while (!(mask & 1)) { + value <<= 1; + mask >>= 1; + } + + return value; +} + +static int do_read(int chip, int fd, unsigned int mask, unsigned int reg, unsigned int *value) +{ + unsigned int command; + int res; + + switch (chip) { + case CHIP_RETU: + command = RETU_IOCH_READ; + break; + case CHIP_TAHVO: + command = TAHVO_IOCH_READ; + break; + default: + return -1; + } + res = ioctl(fd, command, MASKREG(mask, reg)); + if (res < 0) + return -1; + *value = decrapify_value(res, mask); + + return 0; +} + +static int task_read(int chip, unsigned int reg, unsigned int *value) +{ + int fd, err; + + fd = open_dev(chip); + if (fd < 0) + return -1; + err = do_read(chip, fd, 0xFFFF, reg, value); + close(fd); + + return err; +} + +static int do_write(int chip, int fd, unsigned int mask, unsigned int reg, unsigned int value) +{ + struct retu_tahvo_write_parms p; + unsigned int command; + int err; + + switch (chip) { + case CHIP_RETU: + command = RETU_IOCX_WRITE; + break; + case CHIP_TAHVO: + command = TAHVO_IOCX_WRITE; + break; + default: + return -1; + } + + memset(&p, 0, sizeof(p)); + p.field = MASKREG(mask, reg); + p.value = encrapify_value(value, mask); + + err = ioctl(fd, command, &p); + if (err) { + fprintf(stderr, "Write ioctl failed\n"); + return -1; + } + if (p.result != 0) { + fprintf(stderr, "Failed to write\n"); + return -1; + } + + return 0; +} + +static int task_maskset(int chip, unsigned int reg, unsigned int mask, unsigned int set) +{ + int fd, err; + unsigned int value; + + mask &= 0xFFFF; + set &= 0xFFFF; + + fd = open_dev(chip); + if (fd < 0) + return -1; + err = do_write(chip, fd, mask, reg, set); + close(fd); + + return err; +} + +static int task_write(int chip, unsigned int reg, unsigned int value) +{ + return task_maskset(chip, reg, 0xFFFF, value); +} + +static void usage(FILE *fd, int argc, char **argv) +{ + fprintf(fd, "Usage: %s CHIP TASK REG [VALUE...]\n", argv[0]); + fprintf(fd, " CHIP is one of RETU or TAHVO\n"); + fprintf(fd, " TASK is one of READ, WRITE or MASKSET\n"); + fprintf(fd, " VALUE are values, depending on TASK\n"); +} + +int main(int argc, char **argv) +{ + const char *chip_str, *task, *reg_str; + int chip; + unsigned int reg, mask, set, value; + int err; + + if (argc != 4 && argc != 5 && argc != 6) + goto err_usage; + chip_str = argv[1]; + task = argv[2]; + reg_str = argv[3]; + + if (strcasecmp(chip_str, "retu") == 0) + chip = CHIP_RETU; + else if (strcasecmp(chip_str, "tahvo") == 0) + chip = CHIP_TAHVO; + else + goto err_usage; + + err = str2uint(reg_str, ®); + if (err) + goto err_usage; + + if (strcasecmp(task, "read") == 0) { + if (argc != 4) + goto err_usage; + err = task_read(chip, reg, &value); + if (err) { + fprintf(stderr, "Failed to read %s register 0x%02X\n", + chip2str(chip), reg); + return 1; + } + printf("0x%04X\n", value); + } else if (strcasecmp(task, "write") == 0) { + if (argc != 5) + goto err_usage; + err = str2uint(argv[4], &value); + if (err) + goto err_usage; + err = task_write(chip, reg, value); + if (err) { + fprintf(stderr, "Failed to write %s register 0x%02X\n", + chip2str(chip), reg); + return 1; + } + } else if (strcasecmp(task, "maskset") == 0) { + if (argc != 6) + goto err_usage; + err = str2uint(argv[4], &mask); + err |= str2uint(argv[5], &set); + if (err) + goto err_usage; + err = task_maskset(chip, reg, mask, set); + if (err) { + fprintf(stderr, "Failed to maskset %s register 0x%02X\n", + chip2str(chip), reg); + return 1; + } + } else + goto err_usage; + + return 0; + +err_usage: + usage(stderr, argc, argv); + return 1; +} diff --git a/utils/retutahvo/files/src/user_retu_tahvo.h b/utils/retutahvo/files/src/user_retu_tahvo.h new file mode 100644 index 0000000000..a5c219026c --- /dev/null +++ b/utils/retutahvo/files/src/user_retu_tahvo.h @@ -0,0 +1,75 @@ +/** + * drivers/cbus/user_retu_tahvo.h + * + * Copyright (C) 2004, 2005 Nokia Corporation + * + * Written by Mikko Ylinen + * + * Definitions and types used by both retu-user and tahvo-user. + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _USER_RETU_TAHVO_H +#define _USER_RETU_TAHVO_H + +/* Chip IDs */ +#define CHIP_RETU 1 +#define CHIP_TAHVO 2 + +/* Register access type bits */ +#define READ_ONLY 1 +#define WRITE_ONLY 2 +#define READ_WRITE 3 +#define TOGGLE 4 + +#define MASK(field) ((u16)(field & 0xFFFF)) +#define REG(field) ((u16)((field >> 16) & 0x3F)) + +/*** IOCTL definitions. These should be kept in sync with user space **********/ + +#define URT_IOC_MAGIC '`' + +/* + * IOCTL function naming conventions: + * ================================== + * 0 -- No argument and return value + * S -- Set through a pointer + * T -- Tell directly with the argument value + * G -- Reply by setting through a pointer + * Q -- response is on the return value + * X -- S and G atomically + * H -- T and Q atomically + */ + +/* General */ +#define URT_IOCT_IRQ_SUBSCR _IO(URT_IOC_MAGIC, 0) + +/* RETU */ +#define RETU_IOCH_READ _IO(URT_IOC_MAGIC, 1) +#define RETU_IOCX_WRITE _IO(URT_IOC_MAGIC, 2) +#define RETU_IOCH_ADC_READ _IO(URT_IOC_MAGIC, 3) + +/* TAHVO */ +#define TAHVO_IOCH_READ _IO(URT_IOC_MAGIC, 4) +#define TAHVO_IOCX_WRITE _IO(URT_IOC_MAGIC, 5) + +/* This structure is used for writing RETU/TAHVO registers */ +struct retu_tahvo_write_parms { + u32 field; + u16 value; + u8 result; +}; + +#endif -- 2.30.2