From 6339f4670c29f48daef70429401b7de9cf5bea36 Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Thu, 3 Nov 2005 02:44:59 +0000 Subject: 2005-11-02 straumanatslacdotstanford.edu * libi2c/Makefile.am, libi2c/Makefile.in, libi2c/libi2c.c, libi2c/libi2c.h: New files. * Makefile.am, configure.ac, preinstall.am, wrapup/Makefile.am: added a simple API/library for i2c devices and drivers for i2c 2-byte eeproms and a ds1621 temperature sensor; API is documented in libi2c.h --- cpukit/libi2c/.cvsignore | 2 + cpukit/libi2c/Makefile.am | 15 ++ cpukit/libi2c/Makefile.in | 478 +++++++++++++++++++++++++++++++++++++ cpukit/libi2c/libi2c.c | 594 ++++++++++++++++++++++++++++++++++++++++++++++ cpukit/libi2c/libi2c.h | 234 ++++++++++++++++++ 5 files changed, 1323 insertions(+) create mode 100644 cpukit/libi2c/.cvsignore create mode 100644 cpukit/libi2c/Makefile.am create mode 100644 cpukit/libi2c/Makefile.in create mode 100644 cpukit/libi2c/libi2c.c create mode 100644 cpukit/libi2c/libi2c.h (limited to 'cpukit/libi2c') diff --git a/cpukit/libi2c/.cvsignore b/cpukit/libi2c/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/cpukit/libi2c/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/libi2c/Makefile.am b/cpukit/libi2c/Makefile.am new file mode 100644 index 0000000000..c17b4cd6dd --- /dev/null +++ b/cpukit/libi2c/Makefile.am @@ -0,0 +1,15 @@ +## +## $Id$ +## + +include $(top_srcdir)/automake/compile.am + +noinst_LIBRARIES = libi2c.a + +libi2c_a_SOURCES = libi2c.c libi2c.h + +## --- + +all-local: $(PREINSTALL_FILES) + +include $(top_srcdir)/automake/local.am diff --git a/cpukit/libi2c/Makefile.in b/cpukit/libi2c/Makefile.in new file mode 100644 index 0000000000..e1b0ffd997 --- /dev/null +++ b/cpukit/libi2c/Makefile.in @@ -0,0 +1,478 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/automake/compile.am \ + $(top_srcdir)/automake/local.am +subdir = libi2c +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/aclocal/canonical-target-name.m4 \ + $(top_srcdir)/aclocal/canonicalize-tools.m4 \ + $(top_srcdir)/aclocal/check-itron.m4 \ + $(top_srcdir)/aclocal/check-multiprocessing.m4 \ + $(top_srcdir)/aclocal/check-networking.m4 \ + $(top_srcdir)/aclocal/check-newlib.m4 \ + $(top_srcdir)/aclocal/check-posix.m4 \ + $(top_srcdir)/aclocal/check-rtems-debug.m4 \ + $(top_srcdir)/aclocal/check-tool.m4 \ + $(top_srcdir)/aclocal/enable-inlines.m4 \ + $(top_srcdir)/aclocal/enable-itron.m4 \ + $(top_srcdir)/aclocal/enable-multiprocessing.m4 \ + $(top_srcdir)/aclocal/enable-networking.m4 \ + $(top_srcdir)/aclocal/enable-posix.m4 \ + $(top_srcdir)/aclocal/enable-rtems-debug.m4 \ + $(top_srcdir)/aclocal/env-rtemscpu.m4 \ + $(top_srcdir)/aclocal/gcc-pipe.m4 \ + $(top_srcdir)/aclocal/gcc-weak.m4 \ + $(top_srcdir)/aclocal/multi.m4 \ + $(top_srcdir)/aclocal/multilib.m4 \ + $(top_srcdir)/aclocal/prog-cc.m4 \ + $(top_srcdir)/aclocal/prog-ccas.m4 \ + $(top_srcdir)/aclocal/rtems-top.m4 \ + $(top_srcdir)/aclocal/sysv-ipc.m4 \ + $(top_srcdir)/aclocal/version.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libi2c_a_AR = $(AR) $(ARFLAGS) +libi2c_a_LIBADD = +am_libi2c_a_OBJECTS = libi2c.$(OBJEXT) +libi2c_a_OBJECTS = $(am_libi2c_a_OBJECTS) +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libi2c_a_SOURCES) +DIST_SOURCES = $(libi2c_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMPOLISH3 = @AMPOLISH3@ +AMPOLISH3_FALSE = @AMPOLISH3_FALSE@ +AMPOLISH3_TRUE = @AMPOLISH3_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEPRECATED_FALSE = @DEPRECATED_FALSE@ +DEPRECATED_TRUE = @DEPRECATED_TRUE@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +HAS_ITRON_FALSE = @HAS_ITRON_FALSE@ +HAS_ITRON_TRUE = @HAS_ITRON_TRUE@ +HAS_MP_FALSE = @HAS_MP_FALSE@ +HAS_MP_TRUE = @HAS_MP_TRUE@ +HAS_NETWORKING_FALSE = @HAS_NETWORKING_FALSE@ +HAS_NETWORKING_TRUE = @HAS_NETWORKING_TRUE@ +HAS_POSIX_FALSE = @HAS_POSIX_FALSE@ +HAS_POSIX_TRUE = @HAS_POSIX_TRUE@ +INLINE_FALSE = @INLINE_FALSE@ +INLINE_TRUE = @INLINE_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRPC_FALSE = @LIBRPC_FALSE@ +LIBRPC_TRUE = @LIBRPC_TRUE@ +LIBS = @LIBS@ +LIBSERDBG_FALSE = @LIBSERDBG_FALSE@ +LIBSERDBG_TRUE = @LIBSERDBG_TRUE@ +LIBSHELL_FALSE = @LIBSHELL_FALSE@ +LIBSHELL_TRUE = @LIBSHELL_TRUE@ +LTLIBOBJS = @LTLIBOBJS@ +MACROS_FALSE = @MACROS_FALSE@ +MACROS_TRUE = @MACROS_TRUE@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MULTIBUILDTOP = @MULTIBUILDTOP@ +MULTILIB_FALSE = @MULTILIB_FALSE@ +MULTILIB_TRUE = @MULTILIB_TRUE@ +MULTISUBDIR = @MULTISUBDIR@ +NEED_SYS_CDEFS_H_FALSE = @NEED_SYS_CDEFS_H_FALSE@ +NEED_SYS_CDEFS_H_TRUE = @NEED_SYS_CDEFS_H_TRUE@ +NEED_SYS_QUEUE_H_FALSE = @NEED_SYS_QUEUE_H_FALSE@ +NEED_SYS_QUEUE_H_TRUE = @NEED_SYS_QUEUE_H_TRUE@ +NEWLIB_FALSE = @NEWLIB_FALSE@ +NEWLIB_TRUE = @NEWLIB_TRUE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PROJECT_INCLUDE = @PROJECT_INCLUDE@ +PROJECT_LIB = @PROJECT_LIB@ +RANLIB = @RANLIB@ +RTEMS_CFLAGS = @RTEMS_CFLAGS@ +RTEMS_CPPFLAGS = @RTEMS_CPPFLAGS@ +RTEMS_CPU = @RTEMS_CPU@ +RTEMS_HAS_POSIX_API = @RTEMS_HAS_POSIX_API@ +RTEMS_PROVIDES_INTTYPES_H_FALSE = @RTEMS_PROVIDES_INTTYPES_H_FALSE@ +RTEMS_PROVIDES_INTTYPES_H_TRUE = @RTEMS_PROVIDES_INTTYPES_H_TRUE@ +RTEMS_PROVIDES_STDINT_H_FALSE = @RTEMS_PROVIDES_STDINT_H_FALSE@ +RTEMS_PROVIDES_STDINT_H_TRUE = @RTEMS_PROVIDES_STDINT_H_TRUE@ +RTEMS_TOPdir = @RTEMS_TOPdir@ +RTEMS_USE_NEWLIB = @RTEMS_USE_NEWLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_FALSE = @UNIX_FALSE@ +UNIX_TRUE = @UNIX_TRUE@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +dirstamp = @dirstamp@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multilib_basedir = @multilib_basedir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +project_includedir = @project_includedir@ +project_libdir = @project_libdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +AM_CPPFLAGS = -I$(top_builddir) -I$(PROJECT_INCLUDE) +AM_CFLAGS = $(RTEMS_CFLAGS) +AM_CCASFLAGS = -I$(top_builddir) -I$(PROJECT_INCLUDE) $(RTEMS_ASFLAGS) +noinst_LIBRARIES = libi2c.a +libi2c_a_SOURCES = libi2c.c libi2c.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/automake/compile.am $(top_srcdir)/automake/local.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libi2c/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign libi2c/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libi2c.a: $(libi2c_a_OBJECTS) $(libi2c_a_DEPENDENCIES) + -rm -f libi2c.a + $(libi2c_a_AR) libi2c.a $(libi2c_a_OBJECTS) $(libi2c_a_LIBADD) + $(RANLIB) libi2c.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libi2c.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`; \ +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$$depbase.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$$depbase.Tpo" "$$depbase.Po"; else rm -f "$$depbase.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`; \ +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$$depbase.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$$depbase.Tpo" "$$depbase.Po"; else rm -f "$$depbase.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/../automake + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \ + clean-generic clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + + +all-local: $(PREINSTALL_FILES) + +preinstall-am: $(PREINSTALL_FILES) +preinstall: preinstall-am +.PHONY: preinstall preinstall-am + +depend: +.PHONY: depend +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cpukit/libi2c/libi2c.c b/cpukit/libi2c/libi2c.c new file mode 100644 index 0000000000..79fe6525bc --- /dev/null +++ b/cpukit/libi2c/libi2c.c @@ -0,0 +1,594 @@ +/* $Id$ */ + +/* libi2c Implementation */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define DRVNM "libi2c:" + +#define MAX_NO_BUSSES 8 /* Also limited by the macro building minor numbers */ +#define MAX_NO_DRIVERS 16 /* Number of high level drivers we support */ + +#define MINOR2ADDR(minor) ((minor)&((1<<10)-1)) +#define MINOR2BUS(minor) (((minor)>>10)&7) +#define MINOR2DRV(minor) ((minor)>>13) + +/* Check the 'minor' argument, i.e., verify that + * we have a driver connected + */ +#define DECL_CHECKED_BH(b, bh, m, s)\ + unsigned b = MINOR2BUS(m); \ + rtems_libi2c_bus_t *bh; \ + if ( b >= MAX_NO_BUSSES || 0 == (bh=busses[b].bush) ) { \ + return s RTEMS_INVALID_NUMBER; \ + } + +#define DECL_CHECKED_DRV(d, b, m) \ + unsigned d = MINOR2DRV(m); \ + unsigned b = MINOR2BUS(m); \ + if ( b >= MAX_NO_BUSSES || 0 == busses[b].bush \ + || d > MAX_NO_DRIVERS || (d && 0 == drvs[d-1].drv )) {\ + return RTEMS_INVALID_NUMBER; \ + } + +#define DISPATCH(rval, entry, dflt) \ + do { \ + rtems_driver_address_table *ops = drvs[--drv].drv->ops; \ + rval = ops->entry ? ops->entry(major,minor,arg) : dflt; \ + } while (0) + + +rtems_device_major_number rtems_libi2c_major; + +static struct i2cbus +{ + rtems_libi2c_bus_t *bush; + volatile rtems_id mutex; /* lock this across start -> stop */ + volatile short waiting; + volatile char started; + char *name; +} busses[MAX_NO_BUSSES] = { { 0 } }; + +static struct +{ + rtems_libi2c_drv_t *drv; +} drvs[MAX_NO_DRIVERS] = { { 0} }; + +static rtems_id libmutex = 0; + +#define LOCK(m) assert(!rtems_semaphore_obtain((m), RTEMS_WAIT, RTEMS_NO_TIMEOUT)) +#define UNLOCK(m) rtems_semaphore_release((m)) + +#define LIBLOCK() LOCK(libmutex) +#define LIBUNLOCK() UNLOCK(libmutex) + +#define MUTEX_ATTS \ + ( RTEMS_PRIORITY \ + | RTEMS_BINARY_SEMAPHORE \ + |RTEMS_INHERIT_PRIORITY \ + |RTEMS_NO_PRIORITY_CEILING \ + |RTEMS_LOCAL ) + +static rtems_id +mutexCreate (rtems_name nm) +{ + rtems_status_code sc; + rtems_id rval; + if (RTEMS_SUCCESSFUL != + (sc = rtems_semaphore_create (nm, 1, MUTEX_ATTS, 0, &rval))) { + rtems_error (sc, DRVNM " unable to create mutex\n"); + return 0; + } + return rval; +} + +/* Lock a bus avoiding to have a mutex, which is mostly + * unused, hanging around all the time. We just create + * and delete it on the fly... + * + * ASSUMES: argument checked by caller + */ + +static void +lock_bus (int busno) +{ + struct i2cbus *bus = &busses[busno]; + LIBLOCK (); + if (!bus->waiting) { + /* nobody is holding the bus mutex - it's not there. Create it on the fly */ + if (! + (bus->mutex = + mutexCreate (rtems_build_name ('i', '2', 'c', '0' + busno)))) { + LIBUNLOCK (); + rtems_panic (DRVNM " unable to create bus lock"); + } + } + /* count number of people waiting on this bus; only the last one deletes the mutex */ + bus->waiting++; + LIBUNLOCK (); + /* Now lock this bus */ + LOCK (bus->mutex); +} + +static void +unlock_bus (int busno) +{ + struct i2cbus *bus = &busses[busno]; + LIBLOCK (); + UNLOCK (bus->mutex); + if (!--bus->waiting) { + rtems_semaphore_delete (bus->mutex); + } + LIBUNLOCK (); +} + +/* Note that 'arg' is always passed in as NULL */ +static rtems_status_code +i2c_init (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code rval; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == drv) { + rval = 0; + } else { + /* this is probably never called */ + DISPATCH (rval, initialization_entry, RTEMS_SUCCESSFUL); + } + return rval; +} + +static rtems_status_code +i2c_open (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code rval; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == drv) { + rval = RTEMS_SUCCESSFUL; + } else { + DISPATCH (rval, open_entry, RTEMS_SUCCESSFUL); + } + return rval; +} + +static rtems_status_code +i2c_close (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code rval; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == drv) { + rval = RTEMS_SUCCESSFUL; + } else { + DISPATCH (rval, close_entry, RTEMS_SUCCESSFUL); + } + return rval; +} + +static rtems_status_code +i2c_read (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + int rval; /* int so we can check for negative value */ + rtems_libio_rw_args_t *rwargs = arg; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == rwargs->count) { + rwargs->bytes_moved = 0; + return RTEMS_SUCCESSFUL; + } + + if (0 == drv) { + rval = + rtems_libi2c_start_read_bytes (minor, (unsigned char *) rwargs->buffer, + rwargs->count); + if (rval >= 0) { + rwargs->bytes_moved = rval; + rtems_libi2c_send_stop (minor); + rval = RTEMS_SUCCESSFUL; + } else { + rval = -rval; + } + } else { + DISPATCH (rval, read_entry, RTEMS_NOT_IMPLEMENTED); + } + return rval; +} + +static rtems_status_code +i2c_write (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + int rval; /* int so we can check for negative value */ + rtems_libio_rw_args_t *rwargs = arg; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == rwargs->count) { + rwargs->bytes_moved = 0; + return RTEMS_SUCCESSFUL; + } + + if (0 == drv) { + rval = + rtems_libi2c_start_write_bytes (minor, (unsigned char *) rwargs->buffer, + rwargs->count); + if (rval >= 0) { + rwargs->bytes_moved = rval; + rtems_libi2c_send_stop (minor); + rval = RTEMS_SUCCESSFUL; + } else { + rval = -rval; + } + } else { + DISPATCH (rval, write_entry, RTEMS_NOT_IMPLEMENTED); + } + return rval; +} + +static rtems_status_code +i2c_ioctl (rtems_device_major_number major, rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code rval; + DECL_CHECKED_DRV (drv, busno, minor) + + if (0 == drv) { + rval = RTEMS_NOT_IMPLEMENTED; + } else { + DISPATCH (rval, control_entry, RTEMS_NOT_IMPLEMENTED); + } + return rval; +} + + +/* Our ops just dispatch to the registered drivers */ +static rtems_driver_address_table libi2c_io_ops = { + initialization_entry: i2c_init, + open_entry: i2c_open, + close_entry: i2c_close, + read_entry: i2c_read, + write_entry: i2c_write, + control_entry: i2c_ioctl, +}; + + +int +rtems_libi2c_initialize () +{ + rtems_status_code sc; + + if (!(libmutex = mutexCreate (rtems_build_name ('l', 'I', '2', 'C')))) + return -1; + + sc = rtems_io_register_driver (0, &libi2c_io_ops, &rtems_libi2c_major); + if (RTEMS_SUCCESSFUL != 0) { + fprintf (stderr, + DRVNM " Claiming driver slot failed (rtems status code %i)\n", + sc); + rtems_semaphore_delete (libmutex); + libmutex = 0; + return -1; + } + + return 0; +} + +int +rtems_libi2c_register_bus (char *name, rtems_libi2c_bus_t * bus) +{ + int i; + rtems_status_code err; + char *nmcpy = malloc (name ? strlen (name) + 1 : 20); + char tmp, *chpt; + struct stat sbuf; + + strcpy (nmcpy, name ? name : "/dev/i2c"); + + + /* check */ + if ('/' != *nmcpy) { + fprintf (stderr, + "Bad name; must be an absolute path starting with '/'\n"); + return -RTEMS_INVALID_NAME; + } + /* file must not exist */ + if (!stat (nmcpy, &sbuf)) { + fprintf (stderr, "Bad name; file exists already\n"); + return -RTEMS_INVALID_NAME; + } + + /* we already verified that there is at least one '/' */ + chpt = strrchr (nmcpy, '/') + 1; + tmp = *chpt; + *chpt = 0; + i = stat (nmcpy, &sbuf); + *chpt = tmp; + if (i) { + fprintf (stderr, "Bad name '%s'; parent directory doesn't exist\n", + nmcpy); + return -RTEMS_INVALID_NAME; + } + /* should be a directory since name terminates in '/' */ + + + if (!libmutex) { + fprintf (stderr, DRVNM " library not initialized\n"); + return -RTEMS_NOT_DEFINED; + } + + if (bus->size < sizeof (*bus)) { + fprintf (stderr, DRVNM " bus-ops size too small -- misconfiguration?\n"); + return -RTEMS_NOT_CONFIGURED; + } + + LIBLOCK (); + for (i = 0; i < MAX_NO_BUSSES; i++) { + if (!busses[i].bush) { + /* found a free slot */ + busses[i].bush = bus; + busses[i].mutex = 0; + busses[i].waiting = 0; + busses[i].started = 0; + + if (!name) + sprintf (nmcpy + strlen (nmcpy), "%i", i); + + if ((err = busses[i].bush->ops->init (busses[i].bush))) { + /* initialization failed */ + i = -err; + } else { + busses[i].name = nmcpy;; + nmcpy = 0; + } + + break; + } + } + LIBUNLOCK (); + + if (i >= MAX_NO_BUSSES) { + i = -RTEMS_TOO_MANY; + } + + free (nmcpy); + + return i; +} + +static int +not_started (int busno) +{ + int rval; + lock_bus (busno); + rval = !busses[busno].started; + unlock_bus (busno); + return rval; +} + +rtems_status_code +rtems_libi2c_send_start (unsigned32 minor) +{ + int rval; + DECL_CHECKED_BH (busno, bush, minor, +) + + lock_bus (busno); + rval = bush->ops->send_start (bush); + + /* if this failed or is not the first start, unlock */ + if (rval || busses[busno].started) { + /* HMM - what to do if the 1st start failed ? + * try to reset... + */ + if (!busses[busno].started) { + /* just in case the bus driver fiddles with errno */ + int errno_saved = errno; + bush->ops->init (bush); + errno = errno_saved; + } else if (rval) { + /* failed restart */ + rtems_libi2c_send_stop (minor); + } + unlock_bus (busno); + } else { + /* successful 1st start; keep bus locked until stop is sent */ + busses[busno].started = 1; + } + return rval; +} + +rtems_status_code +rtems_libi2c_send_stop (unsigned32 minor) +{ + rtems_status_code rval; + DECL_CHECKED_BH (busno, bush, minor, +) + + if (not_started (busno)) + return RTEMS_NOT_OWNER_OF_RESOURCE; + + rval = bush->ops->send_stop (bush); + + busses[busno].started = 0; + + unlock_bus (busno); + return rval; +} + +rtems_status_code +rtems_libi2c_send_addr (unsigned32 minor, int rw) +{ + rtems_status_code sc; + DECL_CHECKED_BH (busno, bush, minor, +) + + if (not_started (busno)) + return RTEMS_NOT_OWNER_OF_RESOURCE; + + sc = bush->ops->send_addr (bush, MINOR2ADDR (minor), rw); + if (RTEMS_SUCCESSFUL != sc) + rtems_libi2c_send_stop (minor); + return sc; +} + +int +rtems_libi2c_read_bytes (unsigned32 minor, unsigned char *bytes, int nbytes) +{ + int sc; + DECL_CHECKED_BH (busno, bush, minor, -) + + if (not_started (busno)) + return -RTEMS_NOT_OWNER_OF_RESOURCE; + + sc = bush->ops->read_bytes (bush, bytes, nbytes); + if (sc < 0) + rtems_libi2c_send_stop (minor); + return sc; +} + +int +rtems_libi2c_write_bytes (unsigned32 minor, unsigned char *bytes, int nbytes) +{ + int sc; + DECL_CHECKED_BH (busno, bush, minor, -) + + if (not_started (busno)) + return -RTEMS_NOT_OWNER_OF_RESOURCE; + + sc = bush->ops->write_bytes (bush, bytes, nbytes); + if (sc < 0) + rtems_libi2c_send_stop (minor); + return sc; +} + +static int +do_s_rw (unsigned32 minor, unsigned char *bytes, int nbytes, int rw) +{ + rtems_status_code sc; + rtems_libi2c_bus_t *bush; + + if ((sc = rtems_libi2c_send_start (minor))) + return -sc; + + /* at this point, we hold the bus and are sure the minor number is valid */ + bush = busses[MINOR2BUS (minor)].bush; + + if ((sc = bush->ops->send_addr (bush, MINOR2ADDR (minor), rw))) { + rtems_libi2c_send_stop (minor); + return -sc; + } + + if (rw) + sc = bush->ops->read_bytes (bush, bytes, nbytes); + else + sc = bush->ops->write_bytes (bush, bytes, nbytes); + + if (sc < 0) { + rtems_libi2c_send_stop (minor); + } + return sc; +} + +int +rtems_libi2c_start_read_bytes (unsigned32 minor, unsigned char *bytes, + int nbytes) +{ + return do_s_rw (minor, bytes, nbytes, 1); +} + +int +rtems_libi2c_start_write_bytes (unsigned32 minor, unsigned char *bytes, + int nbytes) +{ + return do_s_rw (minor, bytes, nbytes, 0); +} + +int +rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl, + unsigned busno, unsigned i2caddr) +{ + int i; + rtems_status_code err; + rtems_device_minor_number minor; + + if (!libmutex) { + fprintf (stderr, DRVNM " library not initialized\n"); + return -RTEMS_NOT_DEFINED; + } + + if (name && strchr (name, '/')) { + fprintf (stderr, "Invalid name: '%s' -- must not contain '/'\n", name); + return -RTEMS_INVALID_NAME; + } + + if (busno >= MAX_NO_BUSSES || !busses[busno].bush || i2caddr >= 1 << 10) { + errno = EINVAL; + return -RTEMS_INVALID_NUMBER; + } + + if (drvtbl->size < sizeof (*drvtbl)) { + fprintf (stderr, DRVNM " drv-ops size too small -- misconfiguration?\n"); + return -RTEMS_NOT_CONFIGURED; + } + + /* allocate slot */ + LIBLOCK (); + for (i = 0; i < MAX_NO_DRIVERS; i++) { + /* driver # 0 is special, it is the built-in raw driver */ + if (!drvs[i].drv) { + char *str; + dev_t dev; + unsigned32 mode; + + /* found a free slot; encode slot + 1 ! */ + minor = ((i + 1) << 13) | RTEMS_LIBI2C_MAKE_MINOR (busno, i2caddr); + + if (name) { + str = malloc (strlen (busses[busno].name) + strlen (name) + 2); + sprintf (str, "%s.%s", busses[busno].name, name); + + dev = rtems_filesystem_make_dev_t (rtems_libi2c_major, minor); + + mode = 0111 | S_IFCHR; + if (drvtbl->ops->read_entry) + mode |= 0444; + if (drvtbl->ops->write_entry) + mode |= 0222; + + /* note that 'umask' is applied to 'mode' */ + if (mknod (str, mode, dev)) { + fprintf (stderr, + "Creating device node failed: %s; you can try to do it manually...\n", + strerror (errno)); + } + + free (str); + } + + drvs[i].drv = drvtbl; + + if (drvtbl->ops->initialization_entry) + err = + drvs[i].drv->ops->initialization_entry (rtems_libi2c_major, minor, + 0); + else + err = RTEMS_SUCCESSFUL; + + LIBUNLOCK (); + return err ? -err : minor; + } + } + LIBUNLOCK (); + return -RTEMS_TOO_MANY; +} diff --git a/cpukit/libi2c/libi2c.h b/cpukit/libi2c/libi2c.h new file mode 100644 index 0000000000..761e44a9d2 --- /dev/null +++ b/cpukit/libi2c/libi2c.h @@ -0,0 +1,234 @@ +#ifndef RTEMS_LIBI2C_H +#define RTEMS_LIBI2C_H +/*$Id$*/ +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Simple I2C driver API */ + +/* Initialize the libary - may fail if no semaphore or no driver slot is available */ +int rtems_libi2c_initialize (); + +/* Bus Driver API + * + * Bus drivers provide access to low-level i2c functions + * such as 'send start', 'send address', 'get bytes' etc. + */ + +/* first field must be a pointer to ops; driver + * may add its own fields after this. + * the struct that is registered with the library + * is not copied; a pointer will we passed + * to the callback functions (ops). + */ +typedef struct rtems_libi2c_bus_t_ +{ + struct rtems_libi2c_bus_ops_ *ops; + int size; /* size of whole structure */ +} rtems_libi2c_bus_t; + +/* Access functions a low level driver must provide; + * + * All of these, except read_bytes and write_bytes + * return RTEMS_SUCCESSFUL on success and an error status + * otherwise. The read and write ops return the number + * of chars read/written or -(status code) on error. + */ +typedef struct rtems_libi2c_bus_ops_ +{ + /* Initialize the bus; might be called again to reset the bus driver */ + rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl); + /* Send start condition */ + rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl); + /* Send stop condition */ + rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl); + /* initiate transfer from (rw!=0) or to a device */ + rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl, + unsigned32 addr, int rw); + /* read a number of bytes */ + int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes, + int nbytes); + /* write a number of bytes */ + int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes, + int nbytes); +} rtems_libi2c_bus_ops_t; + + +/* + * Register a lowlevel driver + * + * TODO: better description + * + * This allocates a major number identifying *this* driver + * (i.e., libi2c) and the minor number encodes a bus# and a i2c address. + * + * The name will be registered in the filesystem (parent + * directories must exist). It may be NULL in which case + * the library will pick a default. + * + * RETURNS: bus # (>=0) or -1 on error (errno set). + */ + +int rtems_libi2c_register_bus (char *name, rtems_libi2c_bus_t * bus); + +extern rtems_device_major_number rtems_libi2c_major; + +#define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \ + ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1))) + +/* After the library is initialized, a major number is available. + * As soon as a low-level bus driver is registered (above routine + * returns a 'busno'), a device node can be created in the filesystem + * with a major/minor number pair of + * + * rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) + * + * and a 'raw' hi-level driver is then attached to this device + * node. + * This 'raw' driver has very simple semantics: + * + * 'open' sends a start condition + * 'read'/'write' address the device identified by the i2c bus# and address + * encoded in the minor number and read or write, respectively + * a stream of bytes from or to the device. Every time the + * direction is changed, a 're-start' condition followed by + * an 'address' cycle is generated on the i2c bus. + * 'close' sends a stop condition. + * + * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be + * read from an EEPROM by the following pseudo-code: + * + * mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54))) + * + * int fd; + * char off[2]={0x02,0x00}; + * + * fd = open("/dev/i2c-54",O_RDWR); + * write(fd,off,2); + * read(fd,buf,100); + * close(fd); + * + */ + +/* Higher Level Driver API + * + * Higher level drivers know how to deal with specific i2c + * devices (independent of the bus interface chip) and provide + * an abstraction, i.e., the usual read/write/ioctl access. + * + * Using the above example, such a high level driver could + * prevent the user from issuing potentially destructive write + * operations (the aforementioned EEPROM interprets any 3rd + * and following byte written to the device as data, i.e., the + * contents could easily be changed!). + * The correct 'read-pointer offset' programming could be + * implemented in 'open' and 'ioctl' of a high-level driver and + * the user would then only have to perform harmless read + * operations, e.g., + * + * fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * / + * ioctl(fd, IOCTL_SEEK, 0x200) / * repositions the read pointer * / + * read(fd, buf, 100) + * close(fd) + * + */ + +/* struct provided at driver registration. The driver may store + * private data behind the mandatory first fields but the size + * must be set to the size of the entire struct, e.g., + * + * struct driver_pvt { + * rtems_libi2c_drv_t pub; + * struct { ... } pvt; + * } my_driver = { + * { ops: my_ops, + * size: sizeof(my_driver) + * }, + * { ...}; + * }; + * + * A pointer to this struct is passed to the callback ops. + */ + +typedef struct rtems_libi2c_drv_t_ +{ + rtems_driver_address_table *ops; /* the driver ops */ + int size; /* size of whole structure (including appended private data) */ +} rtems_libi2c_drv_t; + +/* + * The high level driver must be registered with a particular + * bus number and i2c address. + * + * The registration procedure also creates a filesystem node, + * i.e., the returned minor number is not really needed. + * + * If the 'name' argument is NULL, no filesystem node is + * created (but this can be done 'manually' using rtems_libi2c_major + * and the return value of this routine). + * + * RETURNS minor number (FYI) or -1 on failure + */ +int +rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl, + unsigned bus, unsigned i2caddr); + +/* Operations available to high level drivers */ + +/* NOTES: The bus a device is attached to is LOCKED from the first send_start + * until send_stop is executed! + * + * Bus tenure MUST NOT span multiple system calls - otherwise, a single + * thread could get into the protected sections (or would deadlock if the + * mutex was not nestable). + * E.g., consider what happens if 'open' sends a 'start' and 'close' + * sends a 'stop' (i.e., the bus mutex would be locked in 'open' and + * released in 'close'. A single thread could try to open two devices + * on the same bus and would either deadlock or nest into the bus mutex + * and potentially mess up the i2c messages. + * + * The correct way is to *always* relinquish the i2c bus (i.e., send 'stop' + * from any driver routine prior to returning control to the caller. + * Consult the implementation of the generic driver routines (open, close, ...) + * below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c + * + * Drivers just pass the minor number on to these routines... + */ +rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor); + +rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor); + +rtems_status_code +rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw); + +/* the read/write routines return the number of bytes transferred + * or -(status_code) on error. + */ +int +rtems_libi2c_read_bytes (rtems_device_minor_number minor, + unsigned char *bytes, int nbytes); + +int +rtems_libi2c_write_bytes (rtems_device_minor_number minor, + unsigned char *bytes, int nbytes); + +/* Send start, send address and read bytes */ +int +rtems_libi2c_start_read_bytes (unsigned32 minor, unsigned char *bytes, + int nbytes); + +/* Send start, send address and write bytes */ +int +rtems_libi2c_start_write_bytes (unsigned32 minor, unsigned char *bytes, + int nbytes); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3