From 33fb66987a6b2a904ee70fafd0a4ef44d0665573 Mon Sep 17 00:00:00 2001 From: Dominic Radermacher Date: Sun, 30 Apr 2017 15:24:49 +0200 Subject: initial commit --- Makefile | 42 ++++++++++++ README | 14 ++++ include/lan951x-led-ctl.h | 64 ++++++++++++++++++ src/lan951x-led-ctl.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 282 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 include/lan951x-led-ctl.h create mode 100644 src/lan951x-led-ctl.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8880aca --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +ECHO = /bin/echo -e +SHELL = /bin/sh +RM = /bin/rm -f +CC = gcc +STRIP = strip + +CFLAGS = -g -Os -std=c11 -I./include -Wall -Wstrict-prototypes -Wconversion +CFLAGS += -Wmissing-prototypes -Wshadow -Wextra -Wunused +LDFLAGS = -lusb-1.0 + +PROGS = lan951x-led-ctl + +all: $(PROGS) + +clean: + $(RM) src/*.o +tidy: + $(RM) src/*.o $(PROGS) + +install: $(PROGS) + @$(ECHO) "\t==> Installing programs to $(DESTDIR)/usr/bin" + @install -m 0755 -d $(DESTDIR)/usr/bin + @install -m 0755 -t $(DESTDIR)/usr/bin $(PROGS) + +pack: + @$(ECHO) "Cleaning up ..." ; \ + $(RM) src/*.o $(PROGS) + @$(ECHO) "Creating package ..." ; \ + VERSION=`cat include/lan951x-led-ctl.h |grep VERSION |cut -d "\"" -f 2` ; \ + cd .. ; \ + tar c -J -f lan951x-led-ctl-$$VERSION.tar.xz lan951x-led-ctl + +# Generic instructions +src/%.o: src/%.c + @$(ECHO) "\t--> Compiling `basename $<`" + @$(CC) $(CFLAGS) -c $< -o $@ + +# Specific programs +lan951x-led-ctl: src/lan951x-led-ctl.o + @$(ECHO) "\t==> Linking objects to output file $@" + @$(CC) $(CFLAGS) $(LDFLAGS) $+ -o $@ + @$(STRIP) $@ diff --git a/README b/README new file mode 100644 index 0000000..e340252 --- /dev/null +++ b/README @@ -0,0 +1,14 @@ + +lan951x-led-ctl is a command line tool to control the LEDs connected to a +LAN9512 or LAN9514 ethernet controller. + +Usually those LEDs show the ethernet status like "Link/Activity", "Speed" and +"Duplex" mode. Using this tool you can turn them off, if you don't like +a disco in your room at night ;-) Or you can turn them on/off from any shell +script to show whatever status you wish. + +These ethernet and USB controllers are used on many embedded computers like +Raspberry PI, Olinuxino and many more. + +Further info can be found at: +http://mockmoon-cybernetics.ch/computer/raspberry-pi/lan951x-led-ctl/ diff --git a/include/lan951x-led-ctl.h b/include/lan951x-led-ctl.h new file mode 100644 index 0000000..5b46aa2 --- /dev/null +++ b/include/lan951x-led-ctl.h @@ -0,0 +1,64 @@ +/* + lan951x-led-ctl - control LEDs of LAN951X ethernet/usb controllers + + Copyright (C) 2015 Dominic Radermacher + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation + + 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 +*/ + +#define VERSION "1.0" + +#define USB_CTRL_TIMEOUT (5000) +#define LAN951X_VENDOR_ID (0x0424) +#define LAN951X_PRODUCT_ID (0xec00) + +/* values taken from kernel driver smsc95xx.h */ +#define USB_VENDOR_REQUEST_WR_REG (0xa0) +#define USB_VENDOR_REQUEST_RD_REG (0xa1) +#define LED_GPIO_CFG (0x24) +/* meaning of the bits in the LED_GPIO_CFG register */ +#define GPDAT0 (1<<0) +#define GPDAT1 (1<<1) +#define GPDAT2 (1<<2) +#define GPDIR0 (1<<4) +#define GPDIR1 (1<<5) +#define GPDIR2 (1<<6) +#define GPCTL0 (1<<16) +#define GPCTL1 (1<<20) +#define GPCTL2 (1<<24) + +#define GP_ALLDIR (GPDIR0 | GPDIR1 | GPDIR2) +#define GP_ALLDAT (GPDAT0 | GPDAT1 | GPDAT2) +#define GP_ALLCTL (GPCTL0 | GPCTL1 | GPCTL2) + +#define DUP_MASK (GPCTL0 | GPDIR0 | GPDAT0) +#define LNK_MASK (GPCTL1 | GPDIR1 | GPDAT1) +#define SPD_MASK (GPCTL2 | GPDIR2 | GPDAT2) + +#define DUPIDX (0) +#define LNKIDX (1) +#define SPDIDX (2) + +#define MODE_OFF 0 +#define MODE_ON 1 +#define MODE_STATUS 2 +#define MODE_KEEP 4 +#define MODE_ERR -1 + +void usage(void); +int ledmode(const char* str); +int parse_args(int argc, char **argv); +libusb_device_handle *lan951x_open(int vid, int pid); +int lan951x_rd_reg(libusb_device_handle *h, uint16_t reg, uint32_t *val); +int lan951x_wr_reg(libusb_device_handle *h, uint16_t reg, uint32_t val); diff --git a/src/lan951x-led-ctl.c b/src/lan951x-led-ctl.c new file mode 100644 index 0000000..c60884c --- /dev/null +++ b/src/lan951x-led-ctl.c @@ -0,0 +1,162 @@ +/* + lan951x-led-ctl - control LEDs of LAN951X ethernet/usb controllers + + Copyright (C) 2015 Dominic Radermacher + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation + + 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 +*/ + +#include +#include /* exit() */ +#include /* strlen() */ +#include +#include +#include "lan951x-led-ctl.h" + +/* global variables */ +int led_arr[3] = { MODE_KEEP, MODE_KEEP, MODE_KEEP }; + +libusb_device_handle *lan951x_open(int vid, int pid) +{ + libusb_device **devs; + libusb_device *dev; + libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc; + int r,i=0; + + if ((libusb_init(NULL)) < 0) { + fprintf(stderr, "libusb_init() failed\n"); + return NULL; + } +// libusb_set_debug(NULL, 3); + if (libusb_get_device_list(NULL, &devs) < 0) { + return NULL; + } + while ((dev=devs[i++]) != NULL) { + if ((r=libusb_get_device_descriptor(dev, &desc)) < 0) { + fprintf(stderr, "failed to get device descriptor"); + libusb_free_device_list(devs, 1); + return NULL; + } + if ((desc.idVendor == vid) && (desc.idProduct == pid)) { +// fprintf(stderr, "LAN951x found on USB bus %d, device %d\n", +// libusb_get_bus_number(dev), +// libusb_get_device_address(dev)); + if ((r=libusb_open(dev, &handle)) != 0) { + fprintf(stderr, "libusb_open error :%s\n", libusb_error_name(r)); + return NULL; + } + libusb_free_device_list(devs, 1); + return handle; + } + } + fprintf(stderr, "No LAN951x found on USB\n"); + libusb_free_device_list(devs, 1); + return NULL; +} + +int lan951x_rd_reg(libusb_device_handle *h, uint16_t reg, uint32_t *val) +{ + return libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR|0x80, + USB_VENDOR_REQUEST_RD_REG, 0, reg, (uint8_t *)val, 4, + USB_CTRL_TIMEOUT); +} + +int lan951x_wr_reg(libusb_device_handle *h, uint16_t reg, uint32_t val) +{ + return libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, + USB_VENDOR_REQUEST_WR_REG, 0, reg, (uint8_t *)&val, 4, + USB_CTRL_TIMEOUT); +} + +int ledmode(const char* s) +{ + if (*s == '0') { + return MODE_OFF; + } else if (*s == '1') { + return MODE_ON; + } else if ((*s == 's') || (*s == 'S')) { + return MODE_STATUS; + } + return MODE_ERR; +} + +void usage(void) +{ + printf("usage: lan951x-led-ctl [--fdx=x][--lnk=x][--spd=x]\n"); + printf("\twhere x is one of:\n"); + printf("\t0 - turn LED off\n\t1 - turn LED on\n\ts - LED shows status\n"); + exit(1); +} + +int parse_args(int argc, char **argv) +{ + int i; + + for (i=1; i