summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@lamia.panaceas.james.local>2015-09-27 11:51:12 +0100
committerroot <root@lamia.panaceas.james.local>2015-09-27 11:51:12 +0100
commitfb709653ff255ef72b3fb3ab10137e104a52750f (patch)
treef2b73897244c8d7ee397a36649512322a6d1675a
parent83ded88a16a3bbc2e9a50902b0b9728e4e50aad3 (diff)
downloadtrunk-47048-pq-fb709653ff255ef72b3fb3ab10137e104a52750f.tar.gz
trunk-47048-pq-fb709653ff255ef72b3fb3ab10137e104a52750f.tar.bz2
trunk-47048-pq-fb709653ff255ef72b3fb3ab10137e104a52750f.zip
cleanup
-rw-r--r--master/config83
-rw-r--r--master/endstop1458
-rw-r--r--master/fix-mjpg-streamer-stack-smashing4
-rw-r--r--master/kkmoon101
-rw-r--r--master/motors1236
-rw-r--r--master/series5
6 files changed, 1425 insertions, 1462 deletions
diff --git a/master/config b/master/config
index f855adf..84c504c 100644
--- a/master/config
+++ b/master/config
@@ -2234,3 +2234,86 @@ index 0000000..e9f4329
+# CONFIG_PACKAGE_uuidgen is not set
+CONFIG_PACKAGE_v4l-utils=y
+# CONFIG_PACKAGE_whereis is not set
+diff --git a/.config b/.config
+index e9f4329..0d33ce6 100644
+--- a/.config
++++ b/.config
+@@ -78,6 +78,7 @@ CONFIG_TARGET_ramips_rt305x=y
+ # CONFIG_TARGET_ramips_rt305x_HT-TM02 is not set
+ # CONFIG_TARGET_ramips_rt305x_HG255D is not set
+ # CONFIG_TARGET_ramips_rt305x_M2M is not set
++CONFIG_TARGET_ramips_rt305x_TP-C516W=y
+ # CONFIG_TARGET_ramips_rt305x_A5-V11 is not set
+ # CONFIG_TARGET_ramips_rt305x_WT1520 is not set
+ # CONFIG_TARGET_ramips_rt305x_RT5350F-OLINUXINO is not set
+@@ -95,7 +96,7 @@ CONFIG_TARGET_ramips_rt305x=y
+ # CONFIG_TARGET_ramips_rt305x_UR-326N4G is not set
+ # CONFIG_TARGET_ramips_rt305x_UR-336UN is not set
+ # CONFIG_TARGET_ramips_rt305x_VOCORE is not set
+-CONFIG_TARGET_ramips_rt305x_NCS601W=y
++# CONFIG_TARGET_ramips_rt305x_NCS601W is not set
+ # CONFIG_TARGET_ramips_rt305x_WIZFI630A is not set
+ CONFIG_HAS_SUBTARGETS=y
+ CONFIG_TARGET_BOARD="ramips"
+@@ -122,6 +123,7 @@ CONFIG_DEFAULT_kmod-video-core=y
+ CONFIG_DEFAULT_kmod-video-uvc=y
+ CONFIG_DEFAULT_libc=y
+ CONFIG_DEFAULT_libgcc=y
++CONFIG_DEFAULT_mjg-streamer=y
+ CONFIG_DEFAULT_mtd=y
+ CONFIG_DEFAULT_netifd=y
+ CONFIG_DEFAULT_odhcp6c=y
+@@ -164,7 +166,7 @@ CONFIG_EXTERNAL_CPIO=""
+ # Root filesystem images
+ #
+ # CONFIG_TARGET_ROOTFS_EXT4FS is not set
+-# CONFIG_TARGET_ROOTFS_JFFS2 is not set
++CONFIG_TARGET_ROOTFS_JFFS2=y
+ CONFIG_TARGET_ROOTFS_SQUASHFS=y
+ CONFIG_TARGET_SQUASHFS_BLOCK_SIZE=256
+ CONFIG_TARGET_UBIFS_FREE_SPACE_FIXUP=y
+@@ -299,7 +301,7 @@ CONFIG_TARGET_SUFFIX="musl"
+ # CONFIG_IB is not set
+ # CONFIG_SDK is not set
+ # CONFIG_MAKE_TOOLCHAIN is not set
+-# CONFIG_IMAGEOPT is not set
++CONFIG_IMAGEOPT=y
+ # CONFIG_PREINITOPT is not set
+ CONFIG_TARGET_PREINIT_SUPPRESS_STDERR=y
+ CONFIG_TARGET_PREINIT_TIMEOUT=2
+@@ -314,16 +316,16 @@ CONFIG_TARGET_INIT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
+ CONFIG_TARGET_INIT_ENV=""
+ CONFIG_TARGET_INIT_CMD="/sbin/init"
+ CONFIG_TARGET_INIT_SUPPRESS_STDERR=y
+-# CONFIG_VERSIONOPT is not set
+-CONFIG_PER_FEED_REPO=y
+-CONFIG_PER_FEED_REPO_ADD_DISABLED=y
+-CONFIG_PER_FEED_REPO_ADD_COMMENTED=y
+-# CONFIG_FEED_packages is not set
+-# CONFIG_FEED_luci is not set
+-# CONFIG_FEED_routing is not set
+-# CONFIG_FEED_telephony is not set
+-# CONFIG_FEED_management is not set
+-# CONFIG_FEED_targets is not set
++CONFIG_VERSIONOPT=y
++CONFIG_VERSION_DIST="OpenWrt"
++CONFIG_VERSION_NICK=""
++CONFIG_VERSION_NUMBER=""
++CONFIG_VERSION_REPO="http://openwrt.panaceas.org/repos/tl-c516w/%v/%T/packages"
++CONFIG_VERSION_MANUFACTURER=""
++CONFIG_VERSION_PRODUCT=""
++CONFIG_VERSION_HWREV=""
++# CONFIG_VERSION_FILENAMES is not set
++# CONFIG_PER_FEED_REPO is not set
+ # CONFIG_SMIMEOPT is not set
+ CONFIG_OPKGSMIME_PASSPHRASE=y
+
+@@ -1296,7 +1298,7 @@ CONFIG_PACKAGE_usign=y
+ # CONFIG_PACKAGE_ar is not set
+ # CONFIG_PACKAGE_binutils is not set
+ # CONFIG_PACKAGE_gdb is not set
+-# CONFIG_PACKAGE_gdbserver is not set
++CONFIG_PACKAGE_gdbserver=m
+ # CONFIG_PACKAGE_objdump is not set
+ # CONFIG_PACKAGE_trace-cmd is not set
+ # CONFIG_PACKAGE_trace-cmd-extra is not set
diff --git a/master/endstop b/master/endstop
index a88ece6..e69de29 100644
--- a/master/endstop
+++ b/master/endstop
@@ -1,1458 +0,0 @@
-diff --git a/.config b/.config
-index e9f4329..0d33ce6 100644
---- a/.config
-+++ b/.config
-@@ -78,6 +78,7 @@ CONFIG_TARGET_ramips_rt305x=y
- # CONFIG_TARGET_ramips_rt305x_HT-TM02 is not set
- # CONFIG_TARGET_ramips_rt305x_HG255D is not set
- # CONFIG_TARGET_ramips_rt305x_M2M is not set
-+CONFIG_TARGET_ramips_rt305x_TP-C516W=y
- # CONFIG_TARGET_ramips_rt305x_A5-V11 is not set
- # CONFIG_TARGET_ramips_rt305x_WT1520 is not set
- # CONFIG_TARGET_ramips_rt305x_RT5350F-OLINUXINO is not set
-@@ -95,7 +96,7 @@ CONFIG_TARGET_ramips_rt305x=y
- # CONFIG_TARGET_ramips_rt305x_UR-326N4G is not set
- # CONFIG_TARGET_ramips_rt305x_UR-336UN is not set
- # CONFIG_TARGET_ramips_rt305x_VOCORE is not set
--CONFIG_TARGET_ramips_rt305x_NCS601W=y
-+# CONFIG_TARGET_ramips_rt305x_NCS601W is not set
- # CONFIG_TARGET_ramips_rt305x_WIZFI630A is not set
- CONFIG_HAS_SUBTARGETS=y
- CONFIG_TARGET_BOARD="ramips"
-@@ -122,6 +123,7 @@ CONFIG_DEFAULT_kmod-video-core=y
- CONFIG_DEFAULT_kmod-video-uvc=y
- CONFIG_DEFAULT_libc=y
- CONFIG_DEFAULT_libgcc=y
-+CONFIG_DEFAULT_mjg-streamer=y
- CONFIG_DEFAULT_mtd=y
- CONFIG_DEFAULT_netifd=y
- CONFIG_DEFAULT_odhcp6c=y
-@@ -164,7 +166,7 @@ CONFIG_EXTERNAL_CPIO=""
- # Root filesystem images
- #
- # CONFIG_TARGET_ROOTFS_EXT4FS is not set
--# CONFIG_TARGET_ROOTFS_JFFS2 is not set
-+CONFIG_TARGET_ROOTFS_JFFS2=y
- CONFIG_TARGET_ROOTFS_SQUASHFS=y
- CONFIG_TARGET_SQUASHFS_BLOCK_SIZE=256
- CONFIG_TARGET_UBIFS_FREE_SPACE_FIXUP=y
-@@ -299,7 +301,7 @@ CONFIG_TARGET_SUFFIX="musl"
- # CONFIG_IB is not set
- # CONFIG_SDK is not set
- # CONFIG_MAKE_TOOLCHAIN is not set
--# CONFIG_IMAGEOPT is not set
-+CONFIG_IMAGEOPT=y
- # CONFIG_PREINITOPT is not set
- CONFIG_TARGET_PREINIT_SUPPRESS_STDERR=y
- CONFIG_TARGET_PREINIT_TIMEOUT=2
-@@ -314,16 +316,16 @@ CONFIG_TARGET_INIT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
- CONFIG_TARGET_INIT_ENV=""
- CONFIG_TARGET_INIT_CMD="/sbin/init"
- CONFIG_TARGET_INIT_SUPPRESS_STDERR=y
--# CONFIG_VERSIONOPT is not set
--CONFIG_PER_FEED_REPO=y
--CONFIG_PER_FEED_REPO_ADD_DISABLED=y
--CONFIG_PER_FEED_REPO_ADD_COMMENTED=y
--# CONFIG_FEED_packages is not set
--# CONFIG_FEED_luci is not set
--# CONFIG_FEED_routing is not set
--# CONFIG_FEED_telephony is not set
--# CONFIG_FEED_management is not set
--# CONFIG_FEED_targets is not set
-+CONFIG_VERSIONOPT=y
-+CONFIG_VERSION_DIST="OpenWrt"
-+CONFIG_VERSION_NICK=""
-+CONFIG_VERSION_NUMBER=""
-+CONFIG_VERSION_REPO="http://openwrt.panaceas.org/repos/tl-c516w/%v/%T/packages"
-+CONFIG_VERSION_MANUFACTURER=""
-+CONFIG_VERSION_PRODUCT=""
-+CONFIG_VERSION_HWREV=""
-+# CONFIG_VERSION_FILENAMES is not set
-+# CONFIG_PER_FEED_REPO is not set
- # CONFIG_SMIMEOPT is not set
- CONFIG_OPKGSMIME_PASSPHRASE=y
-
-@@ -1296,7 +1298,7 @@ CONFIG_PACKAGE_usign=y
- # CONFIG_PACKAGE_ar is not set
- # CONFIG_PACKAGE_binutils is not set
- # CONFIG_PACKAGE_gdb is not set
--# CONFIG_PACKAGE_gdbserver is not set
-+CONFIG_PACKAGE_gdbserver=m
- # CONFIG_PACKAGE_objdump is not set
- # CONFIG_PACKAGE_trace-cmd is not set
- # CONFIG_PACKAGE_trace-cmd-extra is not set
-diff --git a/feeds/packages/multimedia/mjpg-streamer/Makefile b/feeds/packages/multimedia/mjpg-streamer/Makefile
-index e1e0e20..ff98b4d 100644
---- a/feeds/packages/multimedia/mjpg-streamer/Makefile
-+++ b/feeds/packages/multimedia/mjpg-streamer/Makefile
-@@ -88,6 +88,7 @@ ifeq ($(CONFIG_MJPG_STREAMER_INPUT_FILE),y)
- endif
- ifeq ($(CONFIG_MJPG_STREAMER_INPUT_UVC),y)
- $(CP) $(PKG_BUILD_DIR)/input_uvc.so $(1)/usr/lib
-+ $(CP) $(PKG_BUILD_DIR)/input_motors.so $(1)/usr/lib
- endif
- ifeq ($(CONFIG_MJPG_STREAMER_INPUT_TESTPICTURE),y)
- $(CP) $(PKG_BUILD_DIR)/input_testpicture.so $(1)/usr/lib
-diff --git a/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init b/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
-index 06630d4..ea83303 100644
---- a/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
-+++ b/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
-@@ -83,7 +83,7 @@ start_instance() {
- fi
-
- procd_open_instance
-- procd_set_param command "$PROG" --input "$input_arg" --output "$output_arg"
-+ procd_set_param command "$PROG" --input "$input_arg" --input "input_motors.so" --output "$output_arg"
- procd_close_instance
- }
-
-diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch b/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch
-new file mode 100644
-index 0000000..a1a2239
---- /dev/null
-+++ b/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch
-@@ -0,0 +1,13 @@
-+Index: mjpg-streamer-r182/plugins/input_uvc/v4l2uvc.c
-+===================================================================
-+--- a/plugins/input_uvc/v4l2uvc.c
-++++ b/plugins/input_uvc/v4l2uvc.c
-+@@ -130,7 +130,7 @@ int init_videoIn(struct vdIn *vd, char *
-+ return -1;
-+ }
-+
-+- memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(input_format));
-++ memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(struct v4l2_fmtdesc));
-+
-+ if(fmtdesc.pixelformat == format)
-+ pglobal->in[id].currentFormat = pglobal->in[id].formatCount;
-diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch b/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch
-deleted file mode 100644
-index 24ef14e..0000000
---- a/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch
-+++ /dev/null
-@@ -1,13 +0,0 @@
--Index: mjpg-streamer-r182/plugins/input_uvc/v4l2uvc.c
--===================================================================
----- a/mjpg-streamer-r182/plugins/input_uvc/v4l2uvc.c
--+++ b/mjpg-streamer-r182/plugins/input_uvc/v4l2uvc.c
--@@ -130,7 +130,7 @@ int init_videoIn(struct vdIn *vd, char *
-- return -1;
-- }
--
--- memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(input_format));
--+ memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(struct v4l2_fmtdesc));
--
-- if(fmtdesc.pixelformat == format)
-- pglobal->in[id].currentFormat = pglobal->in[id].formatCount;
-diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch b/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch
-new file mode 100644
-index 0000000..5ffdc58
---- /dev/null
-+++ b/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch
-@@ -0,0 +1,906 @@
-+Index: bar/Makefile
-+===================================================================
-+--- bar.orig/Makefile
-++++ bar/Makefile
-+@@ -33,6 +33,7 @@ APP_BINARY = mjpg_streamer
-+
-+ # define the names and targets of the plugins
-+ PLUGINS = input_uvc.so
-++PLUGINS += input_motors.so
-+ PLUGINS += output_file.so
-+ #PLUGINS += output_udp.so
-+ PLUGINS += output_http.so
-+@@ -71,6 +72,9 @@ input_testpicture.so: mjpg_streamer.h ut
-+ make -C plugins/input_testpicture all
-+ cp plugins/input_testpicture/input_testpicture.so .
-+
-++input_motors.so: mjpg_streamer.h utils.h
-++ make -C plugins/input_motors
-++ cp plugins/input_motors/input_motors.so .
-+
-+ ifeq ($(USE_LIBV4L2),true)
-+ input_uvc.so: mjpg_streamer.h utils.h
-+Index: bar/plugins/input_motors/input_motors.c
-+===================================================================
-+--- /dev/null
-++++ bar/plugins/input_motors/input_motors.c
-+@@ -0,0 +1,708 @@
-++/*******************************************************************************
-++# Linux-UVC streaming input-plugin for MJPG-streamer #
-++# #
-++# This package work with the Logitech UVC based webcams with the mjpeg feature #
-++# #
-++# Copyright (C) 2005 2006 Laurent Pinchart && Michel Xhaard #
-++# 2007 Lucas van Staden #
-++# 2007 Tom Stöveken #
-++# #
-++# 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. #
-++# #
-++# 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 <stdio.h>
-++#include <stdlib.h>
-++#include <unistd.h>
-++#include <string.h>
-++#include <fcntl.h>
-++#include <sys/ioctl.h>
-++#include <errno.h>
-++#include <signal.h>
-++#include <sys/socket.h>
-++#include <arpa/inet.h>
-++#include <sys/types.h>
-++#include <sys/stat.h>
-++#include <getopt.h>
-++#include <pthread.h>
-++#include <syslog.h>
-++
-++#include "../../utils.h"
-++#include "../../mjpg_streamer.h"
-++
-++#define INPUT_PLUGIN_NAME "KKMoon motors control"
-++
-++#define MIN_RES 5
-++
-++#if 0
-++#undef DBG
-++#define DBG(a...) do { fprintf(stderr,a); } while (0)
-++#endif
-++
-++
-++#define V_MIN -175
-++#define V_MAX 455
-++
-++#define H_MIN -1040
-++#define H_MAX 1030
-++
-++#define H_STEPS (1+(H_MAX)-(H_MIN))
-++#define V_STEPS (1+(V_MAX)-(V_MIN))
-++
-++
-++
-++typedef struct input_motors
-++{
-++ int fd;
-++ char *device;
-++ int min_res;
-++} input_motors;
-++
-++/* private functions and variables to this plugin */
-++static pthread_t worker;
-++static pthread_mutex_t motor_mutex = PTHREAD_MUTEX_INITIALIZER;
-++static pthread_mutex_t worker_mutex = PTHREAD_MUTEX_INITIALIZER;
-++static pthread_cond_t worker_cond = PTHREAD_COND_INITIALIZER;
-++static input_motors *this;
-++static globals *pglobal;
-++static int plugin_number;
-++
-++
-++static volatile int worker_pan, worker_tilt;
-++
-++static void
-++motor_cmd (int fd, char m, size_t n)
-++{
-++ static char buf[8192];
-++ size_t l;
-++
-++ DBG ("motor: %c for %d\n", m, (int) n);
-++
-++ while (n)
-++ {
-++ l = (n > sizeof (buf)) ? sizeof (buf) : n;
-++ pthread_mutex_lock (&motor_mutex);
-++ memset (buf, m, l);
-++ write (fd, buf, l);
-++ pthread_mutex_unlock (&motor_mutex);
-++ n -= l;
-++ }
-++}
-++
-++static int pan_valid, pan;
-++
-++static void
-++pan_move (int fd, int m)
-++{
-++ DBG ("pan_move: %d\n", m);
-++ if (m < 0)
-++ motor_cmd (fd, 'L', -m);
-++ else
-++ motor_cmd (fd, 'R', m);
-++}
-++
-++
-++static void
-++pan_abs (int fd, int p)
-++{
-++ DBG ("pan_abs: pan_valid=%d pan=%d requested=%d\n", pan_valid, pan, p);
-++
-++ if (!pan_valid)
-++ {
-++ pan_move (fd, -H_STEPS);
-++ pan_valid = 1;
-++ pan = H_MIN;
-++ }
-++
-++ if (p < H_MIN)
-++ p = H_MIN;
-++ if (p > H_MAX)
-++ p = H_MAX;
-++
-++ pan_move (fd, p - pan);
-++
-++ pan = p;
-++}
-++
-++static void
-++pan_rel (int fd, int m)
-++{
-++ DBG ("pan_rel: pan_valid=%d pan=%d requested=%d\n", pan_valid, pan, m);
-++ if (pan_valid)
-++ {
-++ pan_abs (fd, pan + m);
-++ }
-++ else
-++ {
-++ pan_move (fd, m);
-++ }
-++}
-++
-++
-++
-++static int tilt_valid, tilt;
-++
-++static void
-++tilt_move (int fd, int m)
-++{
-++ DBG ("tilt_move: %d\n", m);
-++ if (m < 0)
-++ motor_cmd (fd, 'D', -m);
-++ else
-++ motor_cmd (fd, 'U', m);
-++}
-++
-++
-++static void
-++tilt_abs (int fd, int p)
-++{
-++ DBG ("tilt_abs tilt_valid=%d tilt=%d requested=%d\n", tilt_valid, tilt, p);
-++ if (!tilt_valid)
-++ {
-++ tilt_move (fd, -V_STEPS);
-++ tilt_valid = 1;
-++ tilt = V_MIN;
-++ }
-++
-++ if (p < V_MIN)
-++ p = V_MIN;
-++ if (p > V_MAX)
-++ p = V_MAX;
-++
-++ tilt_move (fd, p - tilt);
-++
-++ tilt = p;
-++}
-++
-++static void
-++tilt_rel (int fd, int m)
-++{
-++ DBG ("tilt_rel tilt_valid=%d tilt=%d requested=%d\n", tilt_valid, tilt, m);
-++ if (tilt_valid)
-++ {
-++ tilt_abs (fd, tilt + m);
-++ }
-++ else
-++ {
-++ tilt_move (fd, m);
-++ }
-++}
-++
-++
-++
-++
-++static void
-++help (void)
-++{
-++ fprintf (stderr,
-++ " ---------------------------------------------------------------\n"
-++ " Help for input plugin..: " INPUT_PLUGIN_NAME "\n"
-++ " ---------------------------------------------------------------\n"
-++ " The following parameters can be passed to this plugin:\n\n"
-++ " [-d | --device ]...: video device to open (your camera)\n"
-++ " [-m | --min ]......: set the minimum step size in phases (defalt 5)\n");
-++}
-++
-++
-++
-++
-++static void
-++worker_cleanup (void *arg)
-++{
-++ static unsigned char first_run = 1;
-++
-++ if (!first_run)
-++ {
-++ DBG ("already cleaned up ressources\n");
-++ return;
-++ }
-++
-++ first_run = 0;
-++}
-++
-++
-++
-++
-++static void *
-++worker_thread (void *arg)
-++{
-++ struct timespec ts = { 0 };
-++ int err;
-++
-++
-++ /* set cleanup handler to cleanup allocated ressources */
-++ pthread_cleanup_push (worker_cleanup, NULL);
-++
-++ while (!pglobal->stop)
-++ {
-++
-++ clock_gettime (CLOCK_MONOTONIC, &ts);
-++
-++ ts.tv_sec += 1;
-++
-++ pthread_mutex_lock (&worker_mutex);
-++ pthread_cond_timedwait (&worker_cond, &worker_mutex, &ts);
-++ pthread_mutex_unlock (&worker_mutex);
-++ while (worker_pan || worker_tilt)
-++ {
-++ if (worker_pan)
-++ pan_rel (this->fd, worker_pan);
-++ if (worker_tilt)
-++ tilt_rel (this->fd, worker_tilt);
-++ }
-++
-++ pthread_cond_broadcast (&pglobal->in[plugin_number].db_update); //this keeps the output stream alive
-++ DBG ("spin loop\n");
-++ }
-++
-++ DBG ("leaving input thread, calling cleanup function now\n");
-++ pthread_cleanup_pop (1);
-++
-++ return NULL;
-++}
-++
-++
-++void
-++add_control (int plugin_number, control c)
-++{
-++ if (!pglobal->in[plugin_number].in_parameters)
-++ {
-++ pglobal->in[plugin_number].in_parameters =
-++ (control *) calloc (1, sizeof (control));
-++ }
-++ else
-++ {
-++ pglobal->in[plugin_number].in_parameters =
-++ (control *) realloc (pglobal->in[plugin_number].in_parameters,
-++ (pglobal->in[plugin_number].parametercount +
-++ 1) * sizeof (control));
-++ }
-++
-++ if (pglobal->in[plugin_number].in_parameters == NULL)
-++ {
-++ DBG ("Calloc failed\n");
-++ return;
-++ }
-++
-++ pglobal->in[plugin_number].in_parameters[pglobal->in[plugin_number].
-++ parametercount] = c;
-++
-++ pglobal->in[plugin_number].parametercount++;
-++
-++}
-++
-++
-++
-++static void
-++add_btn (int plugin_number, unsigned int id, char *name)
-++{
-++
-++ control btn;
-++
-++ btn.group = IN_CMD_GENERIC;
-++ btn.menuitems = NULL;
-++ btn.value = 0.0;
-++ btn.class_id = 0;
-++
-++ btn.ctrl.id = id;
-++ btn.ctrl.type = V4L2_CTRL_TYPE_BUTTON;
-++ strcpy ((char *) btn.ctrl.name, name);
-++ btn.ctrl.minimum = 0;
-++ btn.ctrl.maximum = 1;
-++ btn.ctrl.step = 1;
-++ btn.ctrl.default_value = 0;
-++ btn.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE;
-++
-++ add_control (plugin_number, btn);
-++
-++}
-++
-++static void
-++add_bool (int plugin_number, unsigned int id, char *name)
-++{
-++
-++ control btn;
-++
-++ btn.group = IN_CMD_GENERIC;
-++ btn.menuitems = NULL;
-++ btn.value = 0.0;
-++ btn.class_id = 0;
-++
-++ btn.ctrl.id = id;
-++ btn.ctrl.type = V4L2_CTRL_TYPE_BOOLEAN;
-++ strcpy ((char *) btn.ctrl.name, name);
-++ btn.ctrl.minimum = 0;
-++ btn.ctrl.maximum = 1;
-++ btn.ctrl.step = 1;
-++ btn.ctrl.default_value = 0;
-++ btn.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE;
-++
-++ add_control (plugin_number, btn);
-++
-++}
-++
-++
-++static void
-++add_abs (int plugin_number, unsigned int id, char *name, int max)
-++{
-++
-++ control abs;
-++
-++ abs.group = IN_CMD_GENERIC;
-++ abs.menuitems = NULL;
-++ abs.value = 0xffffff;
-++ abs.class_id = 0;
-++
-++ abs.ctrl.id = id;
-++ abs.ctrl.type = V4L2_CTRL_TYPE_INTEGER;
-++ strcpy ((char *) abs.ctrl.name, name);
-++ abs.ctrl.minimum = -max / 2;
-++ abs.ctrl.maximum = max / 2;
-++ abs.ctrl.step = 1;
-++ abs.ctrl.default_value = 0;
-++ abs.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_SLIDER;
-++
-++ add_control (plugin_number, abs);
-++
-++}
-++
-++
-++static void
-++add_controls (int plugin_number)
-++{
-++ add_btn (plugin_number, IN_CMD_RESET_PAN_TILT, "Reset");
-++#ifdef USE_BUTTONS
-++ add_btn (plugin_number, IN_CMD_PAN_MINUS, "Pan-");
-++ add_btn (plugin_number, IN_CMD_PAN_PLUS, "Pan+");
-++ add_btn (plugin_number, IN_CMD_TILT_MINUS, "Tilt-");
-++ add_btn (plugin_number, IN_CMD_TILT_PLUS, "Tilt+");
-++#else
-++ add_bool (plugin_number, IN_CMD_PAN_MINUS, "Pan-");
-++ add_bool (plugin_number, IN_CMD_PAN_PLUS, "Pan+");
-++ add_bool (plugin_number, IN_CMD_TILT_MINUS, "Tilt-");
-++ add_bool (plugin_number, IN_CMD_TILT_PLUS, "Tilt+");
-++#endif
-++ add_abs (plugin_number, IN_CMD_PAN_SET, "Pan", H_STEPS);
-++ add_abs (plugin_number, IN_CMD_TILT_SET, "Tilt", V_STEPS);
-++
-++}
-++
-++
-++
-++/*** plugin interface functions ***/
-++
-++
-++int
-++input_init (input_parameter * param, int id)
-++{
-++ int i;
-++ char *dev = "/dev/motors";
-++
-++ plugin_number = id;
-++
-++ if (pthread_mutex_init (&motor_mutex, NULL) != 0)
-++ {
-++ IPRINT ("could not initialize mutex variable\n");
-++ exit (EXIT_FAILURE);
-++ }
-++
-++ if (pthread_mutex_init (&worker_mutex, NULL) != 0)
-++ {
-++ IPRINT ("could not initialize mutex variable\n");
-++ exit (EXIT_FAILURE);
-++ }
-++
-++
-++ {
-++ pthread_condattr_t attr;
-++ pthread_condattr_init (&attr);
-++ pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
-++
-++ if (pthread_cond_init (&worker_cond, &attr) != 0)
-++ {
-++ IPRINT ("could not initialize cond variable\n");
-++ exit (EXIT_FAILURE);
-++ }
-++
-++ }
-++
-++
-++
-++ /* keep a pointer to the global variables */
-++ pglobal = param->global;
-++
-++ /* allocate webcam datastructure */
-++ this = malloc (sizeof (struct input_motors));
-++ if (this == NULL)
-++ {
-++ IPRINT ("not enough memory for videoIn\n");
-++ exit (EXIT_FAILURE);
-++ }
-++ memset (this, 0, sizeof (struct input_motors));
-++ this->min_res = MIN_RES;
-++
-++ /* display the parsed values */
-++ IPRINT ("Using motors device.: %s\n", dev);
-++
-++ param->argv[0] = INPUT_PLUGIN_NAME;
-++ asprintf (&param->global->in[id].name, "%s", INPUT_PLUGIN_NAME);
-++
-++ /* show all parameters for DBG purposes */
-++ for (i = 0; i < param->argc; i++)
-++ {
-++ DBG ("argv[%d]=%s\n", i, param->argv[i]);
-++ }
-++
-++ /* parse the parameters */
-++ reset_getopt ();
-++ while (1)
-++ {
-++ int option_index = 0, c = 0;
-++ static struct option long_options[] = {
-++ {"h", no_argument, 0, 0},
-++ {"help", no_argument, 0, 0},
-++ {"d", required_argument, 0, 0},
-++ {"device", required_argument, 0, 0},
-++ {"m", required_argument, 0, 0},
-++ {"min", required_argument, 0, 0},
-++ {0, 0, 0, 0}
-++ };
-++
-++ /* parsing all parameters according to the list above is sufficent */
-++ c =
-++ getopt_long_only (param->argc, param->argv, "", long_options,
-++ &option_index);
-++
-++ /* no more options to parse */
-++ if (c == -1)
-++ break;
-++
-++ /* unrecognized option */
-++ if (c == '?')
-++ {
-++ help ();
-++ return 1;
-++ }
-++
-++ /* dispatch the given options */
-++ switch (option_index)
-++ {
-++ /* h, help */
-++ case 0:
-++ case 1:
-++ DBG ("case 0,1\n");
-++ help ();
-++ return 1;
-++ break;
-++
-++ /* d, device */
-++ case 2:
-++ case 3:
-++ DBG ("case 2,3\n");
-++ dev = strdup (optarg);
-++ break;
-++
-++ case 4:
-++ case 5:
-++ DBG ("case 4,5\n");
-++ this->min_res = atoi (optarg);
-++ break;
-++
-++ default:
-++ DBG ("default case\n");
-++ help ();
-++ return 1;
-++ }
-++ }
-++
-++ asprintf (&this->device, "%s", dev);
-++
-++ if ((this->fd = open (this->device, O_RDWR)) == -1)
-++ {
-++ perror ("ERROR opening motor interface");
-++ return -1;
-++ }
-++
-++
-++ add_controls (plugin_number);
-++
-++ return 0;
-++}
-++
-++/******************************************************************************
-++Description.: Stops the execution of worker thread
-++Input Value.: -
-++Return Value: always 0
-++******************************************************************************/
-++int
-++input_stop (void)
-++{
-++ DBG ("will cancel input thread\n");
-++ pthread_cancel (worker);
-++
-++ return 0;
-++}
-++
-++/******************************************************************************
-++Description.: spins of a worker thread
-++Input Value.: -
-++Return Value: always 0
-++******************************************************************************/
-++int
-++input_run (void)
-++{
-++
-++ pthread_create (&worker, 0, worker_thread, NULL);
-++ pthread_detach (worker);
-++
-++ return 0;
-++}
-++
-++/******************************************************************************
-++Description.: process commands, allows to set certain runtime configurations
-++ and settings like pan/tilt, colors, saturation etc.
-++Input Value.: * cmd specifies the command, a complete list is maintained in
-++ the file "input.h"
-++ * value is used for commands that make use of a parameter.
-++Return Value: depends in the command, for most cases 0 means no errors and
-++ -1 signals an error. This is just rule of thumb, not more!
-++******************************************************************************/
-++int
-++input_cmd_old (in_cmd_type cmd, int value)
-++{
-++ int res = 0;
-++
-++
-++ switch (cmd)
-++ {
-++ case IN_CMD_HELLO:
-++ fprintf (stderr, "Hello from input plugin\n");
-++ break;
-++
-++ case IN_CMD_RESET_PAN_TILT:
-++ case IN_CMD_RESET_PAN_TILT_NO_MUTEX:
-++ DBG ("about to set pan/tilt to default position\n");
-++
-++ pan_abs (this->fd, 0);
-++ tilt_abs (this->fd, 0);
-++
-++ break;
-++
-++ case IN_CMD_PAN_SET:
-++ DBG ("set pan to %d steps\n", value);
-++
-++ pan_abs (this->fd, value);
-++
-++ res = value;
-++ break;
-++
-++ case IN_CMD_PAN_PLUS:
-++ DBG ("pan + %d\n", value);
-++#ifdef USE_BUTTONS
-++ pan_rel (this->fd, this->min_res);
-++ res = this->min_res;
-++#else
-++ worker_pan = value ? this->min_res : 0;
-++ pthread_cond_broadcast (&worker_cond);
-++ res = value;
-++#endif
-++ break;
-++
-++ case IN_CMD_PAN_MINUS:
-++ DBG ("pan - %d\n", value);
-++#ifdef USE_BUTTONS
-++ pan_rel (this->fd, -this->min_res);
-++ res = this->min_res;
-++#else
-++ worker_pan = value ? -this->min_res : 0;
-++ pthread_cond_broadcast (&worker_cond);
-++ res = value;
-++#endif
-++
-++ break;
-++
-++ case IN_CMD_TILT_SET:
-++ DBG ("set tilt to %d degrees\n", value);
-++
-++ tilt_abs (this->fd, value);
-++ res = value;
-++ break;
-++
-++ case IN_CMD_TILT_PLUS:
-++ DBG ("tilt + %d\n", value);
-++#ifdef USE_BUTTONS
-++ tilt_rel (this->fd, this->min_res);
-++
-++ res = this->min_res;
-++#else
-++ worker_tilt = value ? this->min_res : 0;
-++ pthread_cond_broadcast (&worker_cond);
-++ res = value;
-++#endif
-++
-++ break;
-++
-++ case IN_CMD_TILT_MINUS:
-++ DBG ("tilt - %d\n", value);
-++
-++#ifdef USE_BUTTONS
-++ tilt_rel (this->fd, -this->min_res);
-++
-++ res = this->min_res;
-++#else
-++ worker_tilt = value ? -this->min_res : 0;
-++ pthread_cond_broadcast (&worker_cond);
-++ res = value;
-++#endif
-++
-++ break;
-++
-++ default:
-++ DBG ("nothing matched\n");
-++ res = -1;
-++ }
-++
-++
-++ return res;
-++}
-++
-++
-++
-++int
-++input_cmd (int plugin_number, unsigned int control_id, unsigned int group,
-++ int value, char *value_string)
-++{
-++ int ret = -1;
-++ DBG ("Requested cmd (id: %d) for the %d plugin. Group: %d value: %d\n",
-++ control_id, plugin_number, group, value);
-++
-++ if (group != IN_CMD_GENERIC)
-++ return -1;
-++
-++ switch (control_id)
-++ {
-++ case IN_CMD_PAN_MINUS:
-++ case IN_CMD_PAN_PLUS:
-++ case IN_CMD_TILT_MINUS:
-++ case IN_CMD_TILT_PLUS:
-++ case IN_CMD_TILT_SET:
-++ case IN_CMD_PAN_SET:
-++ case IN_CMD_RESET_PAN_TILT:
-++ ret = input_cmd_old (control_id, value);
-++ break;
-++ }
-++
-++ return ret;
-++}
-+Index: bar/plugins/input_motors/Makefile
-+===================================================================
-+--- /dev/null
-++++ bar/plugins/input_motors/Makefile
-+@@ -0,0 +1,24 @@
-++###############################################################
-++#
-++# Purpose: Makefile for "M-JPEG Streamer"
-++# Author.: Tom Stoeveken (TST)
-++# Version: 0.3
-++# License: GPL
-++#
-++###############################################################
-++
-++CC = gcc
-++
-++OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
-++
-++CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
-++#CFLAGS += -DDEBUG
-++
-++all: input_motors.so
-++
-++clean:
-++ rm -f *.a *.o core *~ *.so *.lo
-++
-++input_motors.so: $(OTHER_HEADERS)
-++ $(CC) $(CFLAGS) $(LFLAGS) -o $@ input_motors.c
-++
-+Index: bar/www/index.html
-+===================================================================
-+--- bar.orig/www/index.html
-++++ bar/www/index.html
-+@@ -3,53 +3,87 @@
-+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-+ <head>
-+ <title>MJPG-streamer</title>
-+- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-+- <link rel="stylesheet" href="style.css" type="text/css" />
-++ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-++
-++ <link rel="stylesheet" href="index.css" type="text/css" />
-++
-+ <!--[if IE 6]>
-+ <link rel="stylesheet" href="fix.css" type="text/css" />
-+ <![endif]-->
-+ </head>
-+-
-++
-+ <body>
-+- <div id="sidebar">
-+- <h1>MJPG-Streamer Demo Pages</h1>
-+- <h2>a ressource friendly streaming application</h2>
-+-
-+- <div id="menu">
-+- <a class="active" href="index.html">Home</a>
-+- <a href="static.html">Static</a>
-+- <a href="stream.html">Stream</a>
-+- <a href="java.html">Java</a>
-+- <a href="javascript.html">Javascript</a>
-+- <a href="videolan.html">VideoLAN</a>
-+- <a target="_blank" onClick="window.open(this.href, '_blank'); return false;" href="control.html">Control</a>
-+- <a target="_blank" onClick="window.open(this.href, '_blank'); return false;" href="control_old.html">Control old</a>
-+- </div>
-+-
-+- <h3>Version info:</h3>
-+- <p>v0.1 (Okt 22, 2007)</p>
-+- </div>
-+-
-+- <div id="content">
-+- <h1>About</h1>
-+- <h2>Details about the M-JPEG streamer</h2>
-+-
-+- <h3>Congratulations</h3>
-+- <p>You sucessfully managed to install this streaming webserver. If you can see this page, you can also access the stream of JPGs, which can originate from your webcam for example. This installation consists of these example pages and you may customize the look and content.</p>
-+-
-+- <img src="example.jpg" width="512" height="160" alt="just an image" />
-+- <p>The reason for developing this software was the need of a simple and ressource friendly streaming application for Linux-UVC compatible webcams. The predecessor <i>uvc-streamer</i> is working well, but i wanted to implement a few more ideas. For instance, plugins can be used to process the images. One input plugin copies images to a global variable, multiple output plugins can access those images. For example this webpage is served by the <i>output_http.so</i> plugin.</p>
-+-
-+- <a href="static.html"><img src="/?action=snapshot" width="170" height="128" alt="static image example" /></a>
-+- <p>The image displayed here was grabbed by the input plugin. The HTTP request contains the GET parameters <i>action=snapshot</i>. This requests one single picture from the image-input. To display another example, just click on the picture.</p>
-+
-+- <h3>About the examples</h3>
-+- <p>To view the stream with any browser you may try the <i>javascript</i> or <i>java</i> subpages. Firefox is able to display the M-JPEG-stream directly.</p>
-++ <p id="streamwrap" class="xform-p">
-++ <img id="streamimage" class="x-rotated-180" src="/?action=stream" />
-++ </p>
-++
-++ <script type="text/javascript">
-++
-++ function send_button(command,value) {
-++ action_zone.location='http://10.32.48.227:8080/?action=command_ng&dest=0&plugin=1&id='+command+'&group=0&value='+value;
-++ }
-++
-++ function up_onmousedown()
-++ {
-++ send_button(9,1);
-++ }
-++
-++ function up_onmouseup()
-++ {
-++ send_button(9,0);
-++ }
-++
-++
-++
-++ function down_onmousedown()
-++ {
-++ send_button(10,1);
-++ }
-++
-++ function down_onmouseup()
-++ {
-++ send_button(10,0);
-++ }
-++
-++
-++
-++
-++ function left_onmousedown()
-++ {
-++ send_button(7,1);
-++ }
-++
-++ function left_onmouseup()
-++ {
-++ send_button(7,0);
-++ }
-++
-++
-++ function right_onmousedown()
-++ {
-++ send_button(6,1);
-++ }
-++
-++ function right_onmouseup()
-++ {
-++ send_button(6,0);
-++ }
-++
-++ </script>
-++
-++ <div id="tabs">
-++ <ul id="ul_tabs"></ul>
-++ </div>
-++
-++ <h2>
-++ <span onmouseup="left_onmouseup()" onmousedown="left_onmousedown()" style="border:solid 1px red">←</span>
-++ <span onmouseup="up_onmouseup()" onmousedown="up_onmousedown()" style="border:solid 1px red">↑</span>
-++ <span onmouseup="down_onmouseup()" onmousedown="down_onmousedown()" style="border:solid 1px red">↓</span>
-++ <span onmouseup="right_onmouseup()" onmousedown="right_onmousedown()" style="border:solid 1px red">→</span>
-++ </h2>
-+
-+- <h3>About this server</h3>
-+- <p>This server is running a software written for the MJPG-streamer project. The MJPG-streamer developers can not be made responsible for installations of this software.</p>
-++ <iframe name="action_zone" style="display:none" bgcolor='#d8d8d8'></iframe>
-+
-+- <p>&copy; The <a href="http://mjpg-streamer.sf.net">MJPG-streamer team</a> | Design by <a href="http://andreasviklund.com">Andreas Viklund</a></p>
-+- </div>
-+ </body>
-+ </html>
-+Index: bar/www/index.html
-+===================================================================
-+--- /dev/null
-++++ bar/www/index.css
-+@@ -0,0 +1,5 @@
-++img.x-rotated-180 {
-++ -moz-transform: rotate(180deg);
-++ -webkit-transform: rotate(180deg);
-++}
-++
-diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-index 2f6c624..059aae2 100755
---- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-@@ -15,6 +15,8 @@ platform_check_image() {
-
- case "$board" in
- 3g150b|\
-+ ncs601w|\
-+ tp-c516w|\
- 3g300m|\
- 3g-6200n|\
- 3g-6200nl|\
-diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi
-index 5282e5b..208a962 100644
---- a/target/linux/ramips/dts/rt5350.dtsi
-+++ b/target/linux/ramips/dts/rt5350.dtsi
-@@ -119,6 +119,9 @@
- compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
- reg = <0x660 0x24>;
-
-+ resets = <&rstctrl 13>;
-+ reset-names = "pio";
-+
- interrupt-parent = <&intc>;
- interrupts = <6>;
-
-@@ -131,7 +134,7 @@
- 10 14 18 1c
- 20 24 ];
-
-- status = "disabled";
-+ /*status = "disabled";*/
- };
-
- i2c@900 {
-@@ -165,6 +168,7 @@
-
- status = "disabled";
- };
-+
-
- uartlite@c00 {
- compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
-@@ -189,6 +193,16 @@
- interrupt-parent = <&cpuintc>;
- interrupts = <7>;
- };
-+
-+
-+ /* phydummy {
-+ compatible = "ralink,phydummy";
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&led_pins>;
-+
-+ }; */
-+
- };
-
- pinctrl {
-@@ -214,13 +228,6 @@
- };
- };
-
-- phy_led_pins: phy_led {
-- phy_led {
-- ralink,group = "led";
-- ralink,function = "led";
-- };
-- };
--
- uartlite_pins: uartlite {
- uart {
- ralink,group = "uartlite";
-@@ -241,6 +248,13 @@
- ralink,function = "spi_cs1";
- };
- };
-+
-+ led_pins: phy_led {
-+ phy_led {
-+ ralink,group = "led";
-+ ralink,function = "led";
-+ };
-+ };
- };
-
- rstctrl: rstctrl {
-diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
-index ffff29f..2400261 100644
---- a/target/linux/ramips/image/Makefile
-+++ b/target/linux/ramips/image/Makefile
-@@ -745,6 +745,7 @@ define Image/Build/Profile/Default
- $(call Image/Build/Profile/MZKW300NH2,$(1))
- $(call Image/Build/Profile/NBG-419N,$(1))
- $(call Image/Build/Profile/NCS601W,$(1))
-+ $(call Image/Build/Profile/TP-C516W,$(1))
- $(call Image/Build/Profile/NW718,$(1))
- $(call Image/Build/Profile/MINIEMBWIFI,$(1))
- $(call Image/Build/Profile/MINIEMBPLUG,$(1))
-diff --git a/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch b/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch
-new file mode 100644
-index 0000000..2266282
---- /dev/null
-+++ b/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch
-@@ -0,0 +1,284 @@
-+Index: linux-3.18.21/drivers/misc/Kconfig
-+===================================================================
-+--- linux-3.18.21.orig/drivers/misc/Kconfig
-++++ linux-3.18.21/drivers/misc/Kconfig
-+@@ -515,6 +515,13 @@ config VEXPRESS_SYSCFG
-+ bus. System Configuration interface is one of the possible means
-+ of generating transactions on this bus.
-+
-++config KKMOON_MOTORS
-++ tristate "kkmoon motor support"
-++ depends on GPIOLIB
-++ default m
-++ help
-++ kkmoon motors
-++
-+ source "drivers/misc/c2port/Kconfig"
-+ source "drivers/misc/eeprom/Kconfig"
-+ source "drivers/misc/cb710/Kconfig"
-+Index: linux-3.18.21/drivers/misc/Makefile
-+===================================================================
-+--- linux-3.18.21.orig/drivers/misc/Makefile
-++++ linux-3.18.21/drivers/misc/Makefile
-+@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE) += genwqe/
-+ obj-$(CONFIG_ECHO) += echo/
-+ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
-+ obj-$(CONFIG_CXL_BASE) += cxl/
-++obj-$(CONFIG_KKMOON_MOTORS) += kkmoon-motors.o
-+Index: linux-3.18.21/drivers/misc/kkmoon-motors.c
-+===================================================================
-+--- /dev/null
-++++ linux-3.18.21/drivers/misc/kkmoon-motors.c
-+@@ -0,0 +1,235 @@
-++#include <linux/init.h>
-++#include <linux/module.h>
-++#include <linux/kernel.h>
-++#include <linux/fs.h>
-++#include <linux/miscdevice.h>
-++#include <linux/delay.h>
-++#include <linux/gpio.h>
-++#include <linux/jiffies.h>
-++#include <linux/sched.h>
-++
-++MODULE_LICENSE ("GPL");
-++MODULE_AUTHOR ("James McKenzie");
-++MODULE_DESCRIPTION ("KKMoon motor control");
-++MODULE_VERSION ("0.1");
-++
-++#define GPIO_A0 22
-++#define GPIO_A1 23
-++#define GPIO_A2 24
-++#define GPIO_D 26
-++
-++
-++static int h_phase;
-++static int v_phase;
-++
-++
-++static void
-++latch_addr (int a)
-++{
-++ gpio_set_value (GPIO_A0, ! !(a & 1));
-++ gpio_set_value (GPIO_A1, ! !(a & 2));
-++ gpio_set_value (GPIO_A2, ! !(a & 4));
-++ ndelay (100);
-++}
-++
-++
-++static void
-++latch_off (void)
-++{
-++ int i;
-++ gpio_set_value (GPIO_D, 0);
-++ for (i = 0; i < 8; ++i)
-++ latch_addr (i);
-++}
-++
-++
-++static void
-++latch_set (int a)
-++{
-++ latch_off ();
-++ latch_addr (a);
-++ gpio_set_value (GPIO_D, 1);
-++}
-++
-++static int
-++inc (int p)
-++{
-++ p++;
-++ p %= 4;
-++ return p;
-++}
-++
-++
-++static int
-++dec (int p)
-++{
-++ p += 3;
-++ p %= 4;
-++ return p;
-++}
-++
-++static void
-++turret_left (void)
-++{
-++ latch_set (h_phase+4);
-++ h_phase = dec (h_phase);
-++ latch_set (h_phase+4);
-++}
-++
-++static void
-++turret_right (void)
-++{
-++ latch_set (h_phase+4);
-++ h_phase = inc (h_phase);
-++ latch_set (h_phase+4);
-++}
-++
-++
-++static void
-++turret_down (void)
-++{
-++ latch_set (v_phase);
-++ v_phase = inc (v_phase);
-++ latch_set (v_phase);
-++}
-++
-++
-++
-++static void
-++turrent_up (void)
-++{
-++ latch_set (v_phase);
-++ v_phase = dec (v_phase);
-++ latch_set (v_phase);
-++}
-++
-++void
-++pause (void)
-++{
-++ set_current_state(TASK_UNINTERRUPTIBLE);
-++ schedule_timeout (HZ / 50);
-++}
-++
-++static ssize_t
-++motors_write (struct file *file, const char __user * data, size_t count,
-++ loff_t * ppos)
-++{
-++ char c;
-++ size_t red = 0;
-++
-++ while (count--)
-++ {
-++
-++#if 1
-++ if (copy_from_user (&c, data++, 1))
-++ return EFAULT;
-++#else
-++ printk("cfu=%d\n",(int) copy_from_user (&c, data++, 1));
-++#endif
-++
-++ switch (c)
-++ {
-++ case 'U':
-++ turrent_up ();
-++ pause ();
-++ break;
-++ case 'D':
-++ turret_down ();
-++ pause ();
-++ break;
-++ case 'L':
-++ turret_left ();
-++ pause ();
-++ break;
-++ case 'R':
-++ turret_right ();
-++ pause ();
-++ break;
-++
-++ }
-++
-++
-++ red++;
-++
-++ }
-++
-++ latch_off ();
-++
-++ *ppos = red;
-++
-++ return red;
-++}
-++
-++
-++static const struct file_operations motors_fops = {
-++ .owner = THIS_MODULE,
-++ .write = motors_write,
-++};
-++
-++
-++static struct miscdevice motors_dev = {
-++ MISC_DYNAMIC_MINOR,
-++ "motors",
-++ &motors_fops
-++};
-++
-++
-++
-++
-++
-++
-++
-++
-++static int __init
-++motors_init (void)
-++{
-++ int ret;
-++ printk (KERN_INFO "KKMOON_MOTOR: Initializing\n");
-++
-++ ret = misc_register (&motors_dev);
-++ if (ret)
-++ return ret;
-++
-++
-++ gpio_request (GPIO_A0, "sysfs");
-++ gpio_request (GPIO_A1, "sysfs");
-++ gpio_request (GPIO_A2, "sysfs");
-++ gpio_request (GPIO_D, "sysfs");
-++
-++ gpio_export (GPIO_A0, false);
-++ gpio_export (GPIO_A1, false);
-++ gpio_export (GPIO_A2, false);
-++ gpio_export (GPIO_D, false);
-++
-++ gpio_direction_output (GPIO_A0, 0);
-++ gpio_direction_output (GPIO_A1, 0);
-++ gpio_direction_output (GPIO_A2, 0);
-++ gpio_direction_output (GPIO_D, 0);
-++
-++
-++ latch_off ();
-++
-++ return 0;
-++}
-++
-++static void __exit
-++motors_exit (void)
-++{
-++
-++ latch_off ();
-++
-++ gpio_unexport (GPIO_D);
-++ gpio_unexport (GPIO_A2);
-++ gpio_unexport (GPIO_A1);
-++ gpio_unexport (GPIO_A0);
-++
-++ gpio_free (GPIO_D);
-++ gpio_free (GPIO_A2);
-++ gpio_free (GPIO_A1);
-++ gpio_free (GPIO_A0);
-++
-++ misc_deregister (&motors_dev);
-++}
-++
-++module_init (motors_init);
-++module_exit (motors_exit);
-+Index: linux-3.18.21/drivers/pinctrl/pinctrl-rt2880.c
-+===================================================================
-+--- linux-3.18.21.orig/drivers/pinctrl/pinctrl-rt2880.c
-++++ linux-3.18.21/drivers/pinctrl/pinctrl-rt2880.c
-+@@ -372,6 +372,12 @@ static int rt2880_pinmux_pins(struct rt2
-+ /* pin 0 is always a gpio */
-+ p->gpio[0] = 1;
-+
-++ /*ditto pins 22,23,24,and 26 as we don't have a driver to represent the phy*/
-++ p->gpio[22] = 1;
-++ p->gpio[23] = 1;
-++ p->gpio[24] = 1;
-++ p->gpio[26] = 1;
-++
-+ /* set the pads */
-+ for (i = 0; i < p->max_pins; i++) {
-+ /* strlen("ioXY") + 1 = 5 */
-diff --git a/target/linux/ramips/rt305x/config-3.18 b/target/linux/ramips/rt305x/config-3.18
-index 9c03767..20b69ed 100644
---- a/target/linux/ramips/rt305x/config-3.18
-+++ b/target/linux/ramips/rt305x/config-3.18
-@@ -169,3 +169,4 @@ CONFIG_USB_SUPPORT=y
- CONFIG_USE_OF=y
- CONFIG_WATCHDOG_CORE=y
- CONFIG_ZONE_DMA_FLAG=0
-+CONFIG_KKMOON_MOTORS=y
diff --git a/master/fix-mjpg-streamer-stack-smashing b/master/fix-mjpg-streamer-stack-smashing
index f823b33..f04434e 100644
--- a/master/fix-mjpg-streamer-stack-smashing
+++ b/master/fix-mjpg-streamer-stack-smashing
@@ -1,8 +1,8 @@
-diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch b/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch
+diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch b/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch
new file mode 100644
index 0000000..24ef14e
--- /dev/null
-+++ b/feeds/packages/multimedia/mjpg-streamer/patches/999-fix-stack-smashing.patch
++++ b/feeds/packages/multimedia/mjpg-streamer/patches/998-fix-stack-smashing.patch
@@ -0,0 +1,13 @@
+Index: mjpg-streamer-r182/plugins/input_uvc/v4l2uvc.c
+===================================================================
diff --git a/master/kkmoon b/master/kkmoon
index 3fb9095..92b5937 100644
--- a/master/kkmoon
+++ b/master/kkmoon
@@ -45,3 +45,104 @@ index c24d220..ffff29f 100644
nw718_mtd_size=3801088
Image/Build/Profile/NW718=$(call BuildFirmware/CustomFlashFactory/$(1),$(1),nw718m,NW718,$(nw718_mtd_size),ARA1B4NCRNW718;1,factory)
+diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
+index 2f6c624..059aae2 100755
+--- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
++++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
+@@ -15,6 +15,8 @@ platform_check_image() {
+
+ case "$board" in
+ 3g150b|\
++ ncs601w|\
++ tp-c516w|\
+ 3g300m|\
+ 3g-6200n|\
+ 3g-6200nl|\
+diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi
+index 5282e5b..208a962 100644
+--- a/target/linux/ramips/dts/rt5350.dtsi
++++ b/target/linux/ramips/dts/rt5350.dtsi
+@@ -119,6 +119,9 @@
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ reg = <0x660 0x24>;
+
++ resets = <&rstctrl 13>;
++ reset-names = "pio";
++
+ interrupt-parent = <&intc>;
+ interrupts = <6>;
+
+@@ -131,7 +134,7 @@
+ 10 14 18 1c
+ 20 24 ];
+
+- status = "disabled";
++ /*status = "disabled";*/
+ };
+
+ i2c@900 {
+@@ -165,6 +168,7 @@
+
+ status = "disabled";
+ };
++
+
+ uartlite@c00 {
+ compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+@@ -189,6 +193,16 @@
+ interrupt-parent = <&cpuintc>;
+ interrupts = <7>;
+ };
++
++
++ /* phydummy {
++ compatible = "ralink,phydummy";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&led_pins>;
++
++ }; */
++
+ };
+
+ pinctrl {
+@@ -214,13 +228,6 @@
+ };
+ };
+
+- phy_led_pins: phy_led {
+- phy_led {
+- ralink,group = "led";
+- ralink,function = "led";
+- };
+- };
+-
+ uartlite_pins: uartlite {
+ uart {
+ ralink,group = "uartlite";
+@@ -241,6 +248,13 @@
+ ralink,function = "spi_cs1";
+ };
+ };
++
++ led_pins: phy_led {
++ phy_led {
++ ralink,group = "led";
++ ralink,function = "led";
++ };
++ };
+ };
+
+ rstctrl: rstctrl {
+diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
+index ffff29f..2400261 100644
+--- a/target/linux/ramips/image/Makefile
++++ b/target/linux/ramips/image/Makefile
+@@ -745,6 +745,7 @@ define Image/Build/Profile/Default
+ $(call Image/Build/Profile/MZKW300NH2,$(1))
+ $(call Image/Build/Profile/NBG-419N,$(1))
+ $(call Image/Build/Profile/NCS601W,$(1))
++ $(call Image/Build/Profile/TP-C516W,$(1))
+ $(call Image/Build/Profile/NW718,$(1))
+ $(call Image/Build/Profile/MINIEMBWIFI,$(1))
+ $(call Image/Build/Profile/MINIEMBPLUG,$(1))
diff --git a/master/motors b/master/motors
new file mode 100644
index 0000000..33f4a7c
--- /dev/null
+++ b/master/motors
@@ -0,0 +1,1236 @@
+diff --git a/feeds/packages/multimedia/mjpg-streamer/Makefile b/feeds/packages/multimedia/mjpg-streamer/Makefile
+index e1e0e20..ff98b4d 100644
+--- a/feeds/packages/multimedia/mjpg-streamer/Makefile
++++ b/feeds/packages/multimedia/mjpg-streamer/Makefile
+@@ -88,6 +88,7 @@ ifeq ($(CONFIG_MJPG_STREAMER_INPUT_FILE),y)
+ endif
+ ifeq ($(CONFIG_MJPG_STREAMER_INPUT_UVC),y)
+ $(CP) $(PKG_BUILD_DIR)/input_uvc.so $(1)/usr/lib
++ $(CP) $(PKG_BUILD_DIR)/input_motors.so $(1)/usr/lib
+ endif
+ ifeq ($(CONFIG_MJPG_STREAMER_INPUT_TESTPICTURE),y)
+ $(CP) $(PKG_BUILD_DIR)/input_testpicture.so $(1)/usr/lib
+diff --git a/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init b/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
+index 06630d4..ea83303 100644
+--- a/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
++++ b/feeds/packages/multimedia/mjpg-streamer/files/mjpg-streamer.init
+@@ -83,7 +83,7 @@ start_instance() {
+ fi
+
+ procd_open_instance
+- procd_set_param command "$PROG" --input "$input_arg" --output "$output_arg"
++ procd_set_param command "$PROG" --input "$input_arg" --input "input_motors.so" --output "$output_arg"
+ procd_close_instance
+ }
+
+diff --git a/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch b/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch
+new file mode 100644
+index 0000000..5ffdc58
+--- /dev/null
++++ b/feeds/packages/multimedia/mjpg-streamer/patches/999-motors.patch
+@@ -0,0 +1,906 @@
++Index: bar/Makefile
++===================================================================
++--- bar.orig/Makefile
+++++ bar/Makefile
++@@ -33,6 +33,7 @@ APP_BINARY = mjpg_streamer
++
++ # define the names and targets of the plugins
++ PLUGINS = input_uvc.so
+++PLUGINS += input_motors.so
++ PLUGINS += output_file.so
++ #PLUGINS += output_udp.so
++ PLUGINS += output_http.so
++@@ -71,6 +72,9 @@ input_testpicture.so: mjpg_streamer.h ut
++ make -C plugins/input_testpicture all
++ cp plugins/input_testpicture/input_testpicture.so .
++
+++input_motors.so: mjpg_streamer.h utils.h
+++ make -C plugins/input_motors
+++ cp plugins/input_motors/input_motors.so .
++
++ ifeq ($(USE_LIBV4L2),true)
++ input_uvc.so: mjpg_streamer.h utils.h
++Index: bar/plugins/input_motors/input_motors.c
++===================================================================
++--- /dev/null
+++++ bar/plugins/input_motors/input_motors.c
++@@ -0,0 +1,708 @@
+++/*******************************************************************************
+++# Linux-UVC streaming input-plugin for MJPG-streamer #
+++# #
+++# This package work with the Logitech UVC based webcams with the mjpeg feature #
+++# #
+++# Copyright (C) 2005 2006 Laurent Pinchart && Michel Xhaard #
+++# 2007 Lucas van Staden #
+++# 2007 Tom Stöveken #
+++# #
+++# 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. #
+++# #
+++# 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 <stdio.h>
+++#include <stdlib.h>
+++#include <unistd.h>
+++#include <string.h>
+++#include <fcntl.h>
+++#include <sys/ioctl.h>
+++#include <errno.h>
+++#include <signal.h>
+++#include <sys/socket.h>
+++#include <arpa/inet.h>
+++#include <sys/types.h>
+++#include <sys/stat.h>
+++#include <getopt.h>
+++#include <pthread.h>
+++#include <syslog.h>
+++
+++#include "../../utils.h"
+++#include "../../mjpg_streamer.h"
+++
+++#define INPUT_PLUGIN_NAME "KKMoon motors control"
+++
+++#define MIN_RES 5
+++
+++#if 0
+++#undef DBG
+++#define DBG(a...) do { fprintf(stderr,a); } while (0)
+++#endif
+++
+++
+++#define V_MIN -175
+++#define V_MAX 455
+++
+++#define H_MIN -1040
+++#define H_MAX 1030
+++
+++#define H_STEPS (1+(H_MAX)-(H_MIN))
+++#define V_STEPS (1+(V_MAX)-(V_MIN))
+++
+++
+++
+++typedef struct input_motors
+++{
+++ int fd;
+++ char *device;
+++ int min_res;
+++} input_motors;
+++
+++/* private functions and variables to this plugin */
+++static pthread_t worker;
+++static pthread_mutex_t motor_mutex = PTHREAD_MUTEX_INITIALIZER;
+++static pthread_mutex_t worker_mutex = PTHREAD_MUTEX_INITIALIZER;
+++static pthread_cond_t worker_cond = PTHREAD_COND_INITIALIZER;
+++static input_motors *this;
+++static globals *pglobal;
+++static int plugin_number;
+++
+++
+++static volatile int worker_pan, worker_tilt;
+++
+++static void
+++motor_cmd (int fd, char m, size_t n)
+++{
+++ static char buf[8192];
+++ size_t l;
+++
+++ DBG ("motor: %c for %d\n", m, (int) n);
+++
+++ while (n)
+++ {
+++ l = (n > sizeof (buf)) ? sizeof (buf) : n;
+++ pthread_mutex_lock (&motor_mutex);
+++ memset (buf, m, l);
+++ write (fd, buf, l);
+++ pthread_mutex_unlock (&motor_mutex);
+++ n -= l;
+++ }
+++}
+++
+++static int pan_valid, pan;
+++
+++static void
+++pan_move (int fd, int m)
+++{
+++ DBG ("pan_move: %d\n", m);
+++ if (m < 0)
+++ motor_cmd (fd, 'L', -m);
+++ else
+++ motor_cmd (fd, 'R', m);
+++}
+++
+++
+++static void
+++pan_abs (int fd, int p)
+++{
+++ DBG ("pan_abs: pan_valid=%d pan=%d requested=%d\n", pan_valid, pan, p);
+++
+++ if (!pan_valid)
+++ {
+++ pan_move (fd, -H_STEPS);
+++ pan_valid = 1;
+++ pan = H_MIN;
+++ }
+++
+++ if (p < H_MIN)
+++ p = H_MIN;
+++ if (p > H_MAX)
+++ p = H_MAX;
+++
+++ pan_move (fd, p - pan);
+++
+++ pan = p;
+++}
+++
+++static void
+++pan_rel (int fd, int m)
+++{
+++ DBG ("pan_rel: pan_valid=%d pan=%d requested=%d\n", pan_valid, pan, m);
+++ if (pan_valid)
+++ {
+++ pan_abs (fd, pan + m);
+++ }
+++ else
+++ {
+++ pan_move (fd, m);
+++ }
+++}
+++
+++
+++
+++static int tilt_valid, tilt;
+++
+++static void
+++tilt_move (int fd, int m)
+++{
+++ DBG ("tilt_move: %d\n", m);
+++ if (m < 0)
+++ motor_cmd (fd, 'D', -m);
+++ else
+++ motor_cmd (fd, 'U', m);
+++}
+++
+++
+++static void
+++tilt_abs (int fd, int p)
+++{
+++ DBG ("tilt_abs tilt_valid=%d tilt=%d requested=%d\n", tilt_valid, tilt, p);
+++ if (!tilt_valid)
+++ {
+++ tilt_move (fd, -V_STEPS);
+++ tilt_valid = 1;
+++ tilt = V_MIN;
+++ }
+++
+++ if (p < V_MIN)
+++ p = V_MIN;
+++ if (p > V_MAX)
+++ p = V_MAX;
+++
+++ tilt_move (fd, p - tilt);
+++
+++ tilt = p;
+++}
+++
+++static void
+++tilt_rel (int fd, int m)
+++{
+++ DBG ("tilt_rel tilt_valid=%d tilt=%d requested=%d\n", tilt_valid, tilt, m);
+++ if (tilt_valid)
+++ {
+++ tilt_abs (fd, tilt + m);
+++ }
+++ else
+++ {
+++ tilt_move (fd, m);
+++ }
+++}
+++
+++
+++
+++
+++static void
+++help (void)
+++{
+++ fprintf (stderr,
+++ " ---------------------------------------------------------------\n"
+++ " Help for input plugin..: " INPUT_PLUGIN_NAME "\n"
+++ " ---------------------------------------------------------------\n"
+++ " The following parameters can be passed to this plugin:\n\n"
+++ " [-d | --device ]...: video device to open (your camera)\n"
+++ " [-m | --min ]......: set the minimum step size in phases (defalt 5)\n");
+++}
+++
+++
+++
+++
+++static void
+++worker_cleanup (void *arg)
+++{
+++ static unsigned char first_run = 1;
+++
+++ if (!first_run)
+++ {
+++ DBG ("already cleaned up ressources\n");
+++ return;
+++ }
+++
+++ first_run = 0;
+++}
+++
+++
+++
+++
+++static void *
+++worker_thread (void *arg)
+++{
+++ struct timespec ts = { 0 };
+++ int err;
+++
+++
+++ /* set cleanup handler to cleanup allocated ressources */
+++ pthread_cleanup_push (worker_cleanup, NULL);
+++
+++ while (!pglobal->stop)
+++ {
+++
+++ clock_gettime (CLOCK_MONOTONIC, &ts);
+++
+++ ts.tv_sec += 1;
+++
+++ pthread_mutex_lock (&worker_mutex);
+++ pthread_cond_timedwait (&worker_cond, &worker_mutex, &ts);
+++ pthread_mutex_unlock (&worker_mutex);
+++ while (worker_pan || worker_tilt)
+++ {
+++ if (worker_pan)
+++ pan_rel (this->fd, worker_pan);
+++ if (worker_tilt)
+++ tilt_rel (this->fd, worker_tilt);
+++ }
+++
+++ pthread_cond_broadcast (&pglobal->in[plugin_number].db_update); //this keeps the output stream alive
+++ DBG ("spin loop\n");
+++ }
+++
+++ DBG ("leaving input thread, calling cleanup function now\n");
+++ pthread_cleanup_pop (1);
+++
+++ return NULL;
+++}
+++
+++
+++void
+++add_control (int plugin_number, control c)
+++{
+++ if (!pglobal->in[plugin_number].in_parameters)
+++ {
+++ pglobal->in[plugin_number].in_parameters =
+++ (control *) calloc (1, sizeof (control));
+++ }
+++ else
+++ {
+++ pglobal->in[plugin_number].in_parameters =
+++ (control *) realloc (pglobal->in[plugin_number].in_parameters,
+++ (pglobal->in[plugin_number].parametercount +
+++ 1) * sizeof (control));
+++ }
+++
+++ if (pglobal->in[plugin_number].in_parameters == NULL)
+++ {
+++ DBG ("Calloc failed\n");
+++ return;
+++ }
+++
+++ pglobal->in[plugin_number].in_parameters[pglobal->in[plugin_number].
+++ parametercount] = c;
+++
+++ pglobal->in[plugin_number].parametercount++;
+++
+++}
+++
+++
+++
+++static void
+++add_btn (int plugin_number, unsigned int id, char *name)
+++{
+++
+++ control btn;
+++
+++ btn.group = IN_CMD_GENERIC;
+++ btn.menuitems = NULL;
+++ btn.value = 0.0;
+++ btn.class_id = 0;
+++
+++ btn.ctrl.id = id;
+++ btn.ctrl.type = V4L2_CTRL_TYPE_BUTTON;
+++ strcpy ((char *) btn.ctrl.name, name);
+++ btn.ctrl.minimum = 0;
+++ btn.ctrl.maximum = 1;
+++ btn.ctrl.step = 1;
+++ btn.ctrl.default_value = 0;
+++ btn.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE;
+++
+++ add_control (plugin_number, btn);
+++
+++}
+++
+++static void
+++add_bool (int plugin_number, unsigned int id, char *name)
+++{
+++
+++ control btn;
+++
+++ btn.group = IN_CMD_GENERIC;
+++ btn.menuitems = NULL;
+++ btn.value = 0.0;
+++ btn.class_id = 0;
+++
+++ btn.ctrl.id = id;
+++ btn.ctrl.type = V4L2_CTRL_TYPE_BOOLEAN;
+++ strcpy ((char *) btn.ctrl.name, name);
+++ btn.ctrl.minimum = 0;
+++ btn.ctrl.maximum = 1;
+++ btn.ctrl.step = 1;
+++ btn.ctrl.default_value = 0;
+++ btn.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE;
+++
+++ add_control (plugin_number, btn);
+++
+++}
+++
+++
+++static void
+++add_abs (int plugin_number, unsigned int id, char *name, int max)
+++{
+++
+++ control abs;
+++
+++ abs.group = IN_CMD_GENERIC;
+++ abs.menuitems = NULL;
+++ abs.value = 0xffffff;
+++ abs.class_id = 0;
+++
+++ abs.ctrl.id = id;
+++ abs.ctrl.type = V4L2_CTRL_TYPE_INTEGER;
+++ strcpy ((char *) abs.ctrl.name, name);
+++ abs.ctrl.minimum = -max / 2;
+++ abs.ctrl.maximum = max / 2;
+++ abs.ctrl.step = 1;
+++ abs.ctrl.default_value = 0;
+++ abs.ctrl.flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_SLIDER;
+++
+++ add_control (plugin_number, abs);
+++
+++}
+++
+++
+++static void
+++add_controls (int plugin_number)
+++{
+++ add_btn (plugin_number, IN_CMD_RESET_PAN_TILT, "Reset");
+++#ifdef USE_BUTTONS
+++ add_btn (plugin_number, IN_CMD_PAN_MINUS, "Pan-");
+++ add_btn (plugin_number, IN_CMD_PAN_PLUS, "Pan+");
+++ add_btn (plugin_number, IN_CMD_TILT_MINUS, "Tilt-");
+++ add_btn (plugin_number, IN_CMD_TILT_PLUS, "Tilt+");
+++#else
+++ add_bool (plugin_number, IN_CMD_PAN_MINUS, "Pan-");
+++ add_bool (plugin_number, IN_CMD_PAN_PLUS, "Pan+");
+++ add_bool (plugin_number, IN_CMD_TILT_MINUS, "Tilt-");
+++ add_bool (plugin_number, IN_CMD_TILT_PLUS, "Tilt+");
+++#endif
+++ add_abs (plugin_number, IN_CMD_PAN_SET, "Pan", H_STEPS);
+++ add_abs (plugin_number, IN_CMD_TILT_SET, "Tilt", V_STEPS);
+++
+++}
+++
+++
+++
+++/*** plugin interface functions ***/
+++
+++
+++int
+++input_init (input_parameter * param, int id)
+++{
+++ int i;
+++ char *dev = "/dev/motors";
+++
+++ plugin_number = id;
+++
+++ if (pthread_mutex_init (&motor_mutex, NULL) != 0)
+++ {
+++ IPRINT ("could not initialize mutex variable\n");
+++ exit (EXIT_FAILURE);
+++ }
+++
+++ if (pthread_mutex_init (&worker_mutex, NULL) != 0)
+++ {
+++ IPRINT ("could not initialize mutex variable\n");
+++ exit (EXIT_FAILURE);
+++ }
+++
+++
+++ {
+++ pthread_condattr_t attr;
+++ pthread_condattr_init (&attr);
+++ pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
+++
+++ if (pthread_cond_init (&worker_cond, &attr) != 0)
+++ {
+++ IPRINT ("could not initialize cond variable\n");
+++ exit (EXIT_FAILURE);
+++ }
+++
+++ }
+++
+++
+++
+++ /* keep a pointer to the global variables */
+++ pglobal = param->global;
+++
+++ /* allocate webcam datastructure */
+++ this = malloc (sizeof (struct input_motors));
+++ if (this == NULL)
+++ {
+++ IPRINT ("not enough memory for videoIn\n");
+++ exit (EXIT_FAILURE);
+++ }
+++ memset (this, 0, sizeof (struct input_motors));
+++ this->min_res = MIN_RES;
+++
+++ /* display the parsed values */
+++ IPRINT ("Using motors device.: %s\n", dev);
+++
+++ param->argv[0] = INPUT_PLUGIN_NAME;
+++ asprintf (&param->global->in[id].name, "%s", INPUT_PLUGIN_NAME);
+++
+++ /* show all parameters for DBG purposes */
+++ for (i = 0; i < param->argc; i++)
+++ {
+++ DBG ("argv[%d]=%s\n", i, param->argv[i]);
+++ }
+++
+++ /* parse the parameters */
+++ reset_getopt ();
+++ while (1)
+++ {
+++ int option_index = 0, c = 0;
+++ static struct option long_options[] = {
+++ {"h", no_argument, 0, 0},
+++ {"help", no_argument, 0, 0},
+++ {"d", required_argument, 0, 0},
+++ {"device", required_argument, 0, 0},
+++ {"m", required_argument, 0, 0},
+++ {"min", required_argument, 0, 0},
+++ {0, 0, 0, 0}
+++ };
+++
+++ /* parsing all parameters according to the list above is sufficent */
+++ c =
+++ getopt_long_only (param->argc, param->argv, "", long_options,
+++ &option_index);
+++
+++ /* no more options to parse */
+++ if (c == -1)
+++ break;
+++
+++ /* unrecognized option */
+++ if (c == '?')
+++ {
+++ help ();
+++ return 1;
+++ }
+++
+++ /* dispatch the given options */
+++ switch (option_index)
+++ {
+++ /* h, help */
+++ case 0:
+++ case 1:
+++ DBG ("case 0,1\n");
+++ help ();
+++ return 1;
+++ break;
+++
+++ /* d, device */
+++ case 2:
+++ case 3:
+++ DBG ("case 2,3\n");
+++ dev = strdup (optarg);
+++ break;
+++
+++ case 4:
+++ case 5:
+++ DBG ("case 4,5\n");
+++ this->min_res = atoi (optarg);
+++ break;
+++
+++ default:
+++ DBG ("default case\n");
+++ help ();
+++ return 1;
+++ }
+++ }
+++
+++ asprintf (&this->device, "%s", dev);
+++
+++ if ((this->fd = open (this->device, O_RDWR)) == -1)
+++ {
+++ perror ("ERROR opening motor interface");
+++ return -1;
+++ }
+++
+++
+++ add_controls (plugin_number);
+++
+++ return 0;
+++}
+++
+++/******************************************************************************
+++Description.: Stops the execution of worker thread
+++Input Value.: -
+++Return Value: always 0
+++******************************************************************************/
+++int
+++input_stop (void)
+++{
+++ DBG ("will cancel input thread\n");
+++ pthread_cancel (worker);
+++
+++ return 0;
+++}
+++
+++/******************************************************************************
+++Description.: spins of a worker thread
+++Input Value.: -
+++Return Value: always 0
+++******************************************************************************/
+++int
+++input_run (void)
+++{
+++
+++ pthread_create (&worker, 0, worker_thread, NULL);
+++ pthread_detach (worker);
+++
+++ return 0;
+++}
+++
+++/******************************************************************************
+++Description.: process commands, allows to set certain runtime configurations
+++ and settings like pan/tilt, colors, saturation etc.
+++Input Value.: * cmd specifies the command, a complete list is maintained in
+++ the file "input.h"
+++ * value is used for commands that make use of a parameter.
+++Return Value: depends in the command, for most cases 0 means no errors and
+++ -1 signals an error. This is just rule of thumb, not more!
+++******************************************************************************/
+++int
+++input_cmd_old (in_cmd_type cmd, int value)
+++{
+++ int res = 0;
+++
+++
+++ switch (cmd)
+++ {
+++ case IN_CMD_HELLO:
+++ fprintf (stderr, "Hello from input plugin\n");
+++ break;
+++
+++ case IN_CMD_RESET_PAN_TILT:
+++ case IN_CMD_RESET_PAN_TILT_NO_MUTEX:
+++ DBG ("about to set pan/tilt to default position\n");
+++
+++ pan_abs (this->fd, 0);
+++ tilt_abs (this->fd, 0);
+++
+++ break;
+++
+++ case IN_CMD_PAN_SET:
+++ DBG ("set pan to %d steps\n", value);
+++
+++ pan_abs (this->fd, value);
+++
+++ res = value;
+++ break;
+++
+++ case IN_CMD_PAN_PLUS:
+++ DBG ("pan + %d\n", value);
+++#ifdef USE_BUTTONS
+++ pan_rel (this->fd, this->min_res);
+++ res = this->min_res;
+++#else
+++ worker_pan = value ? this->min_res : 0;
+++ pthread_cond_broadcast (&worker_cond);
+++ res = value;
+++#endif
+++ break;
+++
+++ case IN_CMD_PAN_MINUS:
+++ DBG ("pan - %d\n", value);
+++#ifdef USE_BUTTONS
+++ pan_rel (this->fd, -this->min_res);
+++ res = this->min_res;
+++#else
+++ worker_pan = value ? -this->min_res : 0;
+++ pthread_cond_broadcast (&worker_cond);
+++ res = value;
+++#endif
+++
+++ break;
+++
+++ case IN_CMD_TILT_SET:
+++ DBG ("set tilt to %d degrees\n", value);
+++
+++ tilt_abs (this->fd, value);
+++ res = value;
+++ break;
+++
+++ case IN_CMD_TILT_PLUS:
+++ DBG ("tilt + %d\n", value);
+++#ifdef USE_BUTTONS
+++ tilt_rel (this->fd, this->min_res);
+++
+++ res = this->min_res;
+++#else
+++ worker_tilt = value ? this->min_res : 0;
+++ pthread_cond_broadcast (&worker_cond);
+++ res = value;
+++#endif
+++
+++ break;
+++
+++ case IN_CMD_TILT_MINUS:
+++ DBG ("tilt - %d\n", value);
+++
+++#ifdef USE_BUTTONS
+++ tilt_rel (this->fd, -this->min_res);
+++
+++ res = this->min_res;
+++#else
+++ worker_tilt = value ? -this->min_res : 0;
+++ pthread_cond_broadcast (&worker_cond);
+++ res = value;
+++#endif
+++
+++ break;
+++
+++ default:
+++ DBG ("nothing matched\n");
+++ res = -1;
+++ }
+++
+++
+++ return res;
+++}
+++
+++
+++
+++int
+++input_cmd (int plugin_number, unsigned int control_id, unsigned int group,
+++ int value, char *value_string)
+++{
+++ int ret = -1;
+++ DBG ("Requested cmd (id: %d) for the %d plugin. Group: %d value: %d\n",
+++ control_id, plugin_number, group, value);
+++
+++ if (group != IN_CMD_GENERIC)
+++ return -1;
+++
+++ switch (control_id)
+++ {
+++ case IN_CMD_PAN_MINUS:
+++ case IN_CMD_PAN_PLUS:
+++ case IN_CMD_TILT_MINUS:
+++ case IN_CMD_TILT_PLUS:
+++ case IN_CMD_TILT_SET:
+++ case IN_CMD_PAN_SET:
+++ case IN_CMD_RESET_PAN_TILT:
+++ ret = input_cmd_old (control_id, value);
+++ break;
+++ }
+++
+++ return ret;
+++}
++Index: bar/plugins/input_motors/Makefile
++===================================================================
++--- /dev/null
+++++ bar/plugins/input_motors/Makefile
++@@ -0,0 +1,24 @@
+++###############################################################
+++#
+++# Purpose: Makefile for "M-JPEG Streamer"
+++# Author.: Tom Stoeveken (TST)
+++# Version: 0.3
+++# License: GPL
+++#
+++###############################################################
+++
+++CC = gcc
+++
+++OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
+++
+++CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
+++#CFLAGS += -DDEBUG
+++
+++all: input_motors.so
+++
+++clean:
+++ rm -f *.a *.o core *~ *.so *.lo
+++
+++input_motors.so: $(OTHER_HEADERS)
+++ $(CC) $(CFLAGS) $(LFLAGS) -o $@ input_motors.c
+++
++Index: bar/www/index.html
++===================================================================
++--- bar.orig/www/index.html
+++++ bar/www/index.html
++@@ -3,53 +3,87 @@
++ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
++ <head>
++ <title>MJPG-streamer</title>
++- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
++- <link rel="stylesheet" href="style.css" type="text/css" />
+++ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+++
+++ <link rel="stylesheet" href="index.css" type="text/css" />
+++
++ <!--[if IE 6]>
++ <link rel="stylesheet" href="fix.css" type="text/css" />
++ <![endif]-->
++ </head>
++-
+++
++ <body>
++- <div id="sidebar">
++- <h1>MJPG-Streamer Demo Pages</h1>
++- <h2>a ressource friendly streaming application</h2>
++-
++- <div id="menu">
++- <a class="active" href="index.html">Home</a>
++- <a href="static.html">Static</a>
++- <a href="stream.html">Stream</a>
++- <a href="java.html">Java</a>
++- <a href="javascript.html">Javascript</a>
++- <a href="videolan.html">VideoLAN</a>
++- <a target="_blank" onClick="window.open(this.href, '_blank'); return false;" href="control.html">Control</a>
++- <a target="_blank" onClick="window.open(this.href, '_blank'); return false;" href="control_old.html">Control old</a>
++- </div>
++-
++- <h3>Version info:</h3>
++- <p>v0.1 (Okt 22, 2007)</p>
++- </div>
++-
++- <div id="content">
++- <h1>About</h1>
++- <h2>Details about the M-JPEG streamer</h2>
++-
++- <h3>Congratulations</h3>
++- <p>You sucessfully managed to install this streaming webserver. If you can see this page, you can also access the stream of JPGs, which can originate from your webcam for example. This installation consists of these example pages and you may customize the look and content.</p>
++-
++- <img src="example.jpg" width="512" height="160" alt="just an image" />
++- <p>The reason for developing this software was the need of a simple and ressource friendly streaming application for Linux-UVC compatible webcams. The predecessor <i>uvc-streamer</i> is working well, but i wanted to implement a few more ideas. For instance, plugins can be used to process the images. One input plugin copies images to a global variable, multiple output plugins can access those images. For example this webpage is served by the <i>output_http.so</i> plugin.</p>
++-
++- <a href="static.html"><img src="/?action=snapshot" width="170" height="128" alt="static image example" /></a>
++- <p>The image displayed here was grabbed by the input plugin. The HTTP request contains the GET parameters <i>action=snapshot</i>. This requests one single picture from the image-input. To display another example, just click on the picture.</p>
++
++- <h3>About the examples</h3>
++- <p>To view the stream with any browser you may try the <i>javascript</i> or <i>java</i> subpages. Firefox is able to display the M-JPEG-stream directly.</p>
+++ <p id="streamwrap" class="xform-p">
+++ <img id="streamimage" class="x-rotated-180" src="/?action=stream" />
+++ </p>
+++
+++ <script type="text/javascript">
+++
+++ function send_button(command,value) {
+++ action_zone.location='http://10.32.48.227:8080/?action=command_ng&dest=0&plugin=1&id='+command+'&group=0&value='+value;
+++ }
+++
+++ function up_onmousedown()
+++ {
+++ send_button(9,1);
+++ }
+++
+++ function up_onmouseup()
+++ {
+++ send_button(9,0);
+++ }
+++
+++
+++
+++ function down_onmousedown()
+++ {
+++ send_button(10,1);
+++ }
+++
+++ function down_onmouseup()
+++ {
+++ send_button(10,0);
+++ }
+++
+++
+++
+++
+++ function left_onmousedown()
+++ {
+++ send_button(7,1);
+++ }
+++
+++ function left_onmouseup()
+++ {
+++ send_button(7,0);
+++ }
+++
+++
+++ function right_onmousedown()
+++ {
+++ send_button(6,1);
+++ }
+++
+++ function right_onmouseup()
+++ {
+++ send_button(6,0);
+++ }
+++
+++ </script>
+++
+++ <div id="tabs">
+++ <ul id="ul_tabs"></ul>
+++ </div>
+++
+++ <h2>
+++ <span onmouseup="left_onmouseup()" onmousedown="left_onmousedown()" style="border:solid 1px red">←</span>
+++ <span onmouseup="up_onmouseup()" onmousedown="up_onmousedown()" style="border:solid 1px red">↑</span>
+++ <span onmouseup="down_onmouseup()" onmousedown="down_onmousedown()" style="border:solid 1px red">↓</span>
+++ <span onmouseup="right_onmouseup()" onmousedown="right_onmousedown()" style="border:solid 1px red">→</span>
+++ </h2>
++
++- <h3>About this server</h3>
++- <p>This server is running a software written for the MJPG-streamer project. The MJPG-streamer developers can not be made responsible for installations of this software.</p>
+++ <iframe name="action_zone" style="display:none" bgcolor='#d8d8d8'></iframe>
++
++- <p>&copy; The <a href="http://mjpg-streamer.sf.net">MJPG-streamer team</a> | Design by <a href="http://andreasviklund.com">Andreas Viklund</a></p>
++- </div>
++ </body>
++ </html>
++Index: bar/www/index.html
++===================================================================
++--- /dev/null
+++++ bar/www/index.css
++@@ -0,0 +1,5 @@
+++img.x-rotated-180 {
+++ -moz-transform: rotate(180deg);
+++ -webkit-transform: rotate(180deg);
+++}
+++
+diff --git a/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch b/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch
+new file mode 100644
+index 0000000..2266282
+--- /dev/null
++++ b/target/linux/ramips/patches-3.18/9999-kkmoon-motors.patch
+@@ -0,0 +1,284 @@
++Index: linux-3.18.21/drivers/misc/Kconfig
++===================================================================
++--- linux-3.18.21.orig/drivers/misc/Kconfig
+++++ linux-3.18.21/drivers/misc/Kconfig
++@@ -515,6 +515,13 @@ config VEXPRESS_SYSCFG
++ bus. System Configuration interface is one of the possible means
++ of generating transactions on this bus.
++
+++config KKMOON_MOTORS
+++ tristate "kkmoon motor support"
+++ depends on GPIOLIB
+++ default m
+++ help
+++ kkmoon motors
+++
++ source "drivers/misc/c2port/Kconfig"
++ source "drivers/misc/eeprom/Kconfig"
++ source "drivers/misc/cb710/Kconfig"
++Index: linux-3.18.21/drivers/misc/Makefile
++===================================================================
++--- linux-3.18.21.orig/drivers/misc/Makefile
+++++ linux-3.18.21/drivers/misc/Makefile
++@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE) += genwqe/
++ obj-$(CONFIG_ECHO) += echo/
++ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
++ obj-$(CONFIG_CXL_BASE) += cxl/
+++obj-$(CONFIG_KKMOON_MOTORS) += kkmoon-motors.o
++Index: linux-3.18.21/drivers/misc/kkmoon-motors.c
++===================================================================
++--- /dev/null
+++++ linux-3.18.21/drivers/misc/kkmoon-motors.c
++@@ -0,0 +1,235 @@
+++#include <linux/init.h>
+++#include <linux/module.h>
+++#include <linux/kernel.h>
+++#include <linux/fs.h>
+++#include <linux/miscdevice.h>
+++#include <linux/delay.h>
+++#include <linux/gpio.h>
+++#include <linux/jiffies.h>
+++#include <linux/sched.h>
+++
+++MODULE_LICENSE ("GPL");
+++MODULE_AUTHOR ("James McKenzie");
+++MODULE_DESCRIPTION ("KKMoon motor control");
+++MODULE_VERSION ("0.1");
+++
+++#define GPIO_A0 22
+++#define GPIO_A1 23
+++#define GPIO_A2 24
+++#define GPIO_D 26
+++
+++
+++static int h_phase;
+++static int v_phase;
+++
+++
+++static void
+++latch_addr (int a)
+++{
+++ gpio_set_value (GPIO_A0, ! !(a & 1));
+++ gpio_set_value (GPIO_A1, ! !(a & 2));
+++ gpio_set_value (GPIO_A2, ! !(a & 4));
+++ ndelay (100);
+++}
+++
+++
+++static void
+++latch_off (void)
+++{
+++ int i;
+++ gpio_set_value (GPIO_D, 0);
+++ for (i = 0; i < 8; ++i)
+++ latch_addr (i);
+++}
+++
+++
+++static void
+++latch_set (int a)
+++{
+++ latch_off ();
+++ latch_addr (a);
+++ gpio_set_value (GPIO_D, 1);
+++}
+++
+++static int
+++inc (int p)
+++{
+++ p++;
+++ p %= 4;
+++ return p;
+++}
+++
+++
+++static int
+++dec (int p)
+++{
+++ p += 3;
+++ p %= 4;
+++ return p;
+++}
+++
+++static void
+++turret_left (void)
+++{
+++ latch_set (h_phase+4);
+++ h_phase = dec (h_phase);
+++ latch_set (h_phase+4);
+++}
+++
+++static void
+++turret_right (void)
+++{
+++ latch_set (h_phase+4);
+++ h_phase = inc (h_phase);
+++ latch_set (h_phase+4);
+++}
+++
+++
+++static void
+++turret_down (void)
+++{
+++ latch_set (v_phase);
+++ v_phase = inc (v_phase);
+++ latch_set (v_phase);
+++}
+++
+++
+++
+++static void
+++turrent_up (void)
+++{
+++ latch_set (v_phase);
+++ v_phase = dec (v_phase);
+++ latch_set (v_phase);
+++}
+++
+++void
+++pause (void)
+++{
+++ set_current_state(TASK_UNINTERRUPTIBLE);
+++ schedule_timeout (HZ / 50);
+++}
+++
+++static ssize_t
+++motors_write (struct file *file, const char __user * data, size_t count,
+++ loff_t * ppos)
+++{
+++ char c;
+++ size_t red = 0;
+++
+++ while (count--)
+++ {
+++
+++#if 1
+++ if (copy_from_user (&c, data++, 1))
+++ return EFAULT;
+++#else
+++ printk("cfu=%d\n",(int) copy_from_user (&c, data++, 1));
+++#endif
+++
+++ switch (c)
+++ {
+++ case 'U':
+++ turrent_up ();
+++ pause ();
+++ break;
+++ case 'D':
+++ turret_down ();
+++ pause ();
+++ break;
+++ case 'L':
+++ turret_left ();
+++ pause ();
+++ break;
+++ case 'R':
+++ turret_right ();
+++ pause ();
+++ break;
+++
+++ }
+++
+++
+++ red++;
+++
+++ }
+++
+++ latch_off ();
+++
+++ *ppos = red;
+++
+++ return red;
+++}
+++
+++
+++static const struct file_operations motors_fops = {
+++ .owner = THIS_MODULE,
+++ .write = motors_write,
+++};
+++
+++
+++static struct miscdevice motors_dev = {
+++ MISC_DYNAMIC_MINOR,
+++ "motors",
+++ &motors_fops
+++};
+++
+++
+++
+++
+++
+++
+++
+++
+++static int __init
+++motors_init (void)
+++{
+++ int ret;
+++ printk (KERN_INFO "KKMOON_MOTOR: Initializing\n");
+++
+++ ret = misc_register (&motors_dev);
+++ if (ret)
+++ return ret;
+++
+++
+++ gpio_request (GPIO_A0, "sysfs");
+++ gpio_request (GPIO_A1, "sysfs");
+++ gpio_request (GPIO_A2, "sysfs");
+++ gpio_request (GPIO_D, "sysfs");
+++
+++ gpio_export (GPIO_A0, false);
+++ gpio_export (GPIO_A1, false);
+++ gpio_export (GPIO_A2, false);
+++ gpio_export (GPIO_D, false);
+++
+++ gpio_direction_output (GPIO_A0, 0);
+++ gpio_direction_output (GPIO_A1, 0);
+++ gpio_direction_output (GPIO_A2, 0);
+++ gpio_direction_output (GPIO_D, 0);
+++
+++
+++ latch_off ();
+++
+++ return 0;
+++}
+++
+++static void __exit
+++motors_exit (void)
+++{
+++
+++ latch_off ();
+++
+++ gpio_unexport (GPIO_D);
+++ gpio_unexport (GPIO_A2);
+++ gpio_unexport (GPIO_A1);
+++ gpio_unexport (GPIO_A0);
+++
+++ gpio_free (GPIO_D);
+++ gpio_free (GPIO_A2);
+++ gpio_free (GPIO_A1);
+++ gpio_free (GPIO_A0);
+++
+++ misc_deregister (&motors_dev);
+++}
+++
+++module_init (motors_init);
+++module_exit (motors_exit);
++Index: linux-3.18.21/drivers/pinctrl/pinctrl-rt2880.c
++===================================================================
++--- linux-3.18.21.orig/drivers/pinctrl/pinctrl-rt2880.c
+++++ linux-3.18.21/drivers/pinctrl/pinctrl-rt2880.c
++@@ -372,6 +372,12 @@ static int rt2880_pinmux_pins(struct rt2
++ /* pin 0 is always a gpio */
++ p->gpio[0] = 1;
++
+++ /*ditto pins 22,23,24,and 26 as we don't have a driver to represent the phy*/
+++ p->gpio[22] = 1;
+++ p->gpio[23] = 1;
+++ p->gpio[24] = 1;
+++ p->gpio[26] = 1;
+++
++ /* set the pads */
++ for (i = 0; i < p->max_pins; i++) {
++ /* strlen("ioXY") + 1 = 5 */
+diff --git a/target/linux/ramips/rt305x/config-3.18 b/target/linux/ramips/rt305x/config-3.18
+index 9c03767..20b69ed 100644
+--- a/target/linux/ramips/rt305x/config-3.18
++++ b/target/linux/ramips/rt305x/config-3.18
+@@ -169,3 +169,4 @@ CONFIG_USB_SUPPORT=y
+ CONFIG_USE_OF=y
+ CONFIG_WATCHDOG_CORE=y
+ CONFIG_ZONE_DMA_FLAG=0
++CONFIG_KKMOON_MOTORS=y
diff --git a/master/series b/master/series
index e15362e..e8ddeda 100644
--- a/master/series
+++ b/master/series
@@ -1,5 +1,6 @@
feeds
-config
-kkmoon
fix-mjpg-streamer-stack-smashing
+kkmoon
+motors
+config
endstop