lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

172-add-TEW673GRU-driver.patch (12962B)


      1 --- a/drivers.m4
      2 +++ b/drivers.m4
      3 @@ -39,7 +39,7 @@ AC_ARG_WITH(
      4    [                        Newhaven, Noritake, NULL, Pertelian, PHAnderson,]
      5    [                        PICGraphic, picoLCD, picoLCDGraphic, PNG, PPM, RouterBoard,]
      6    [                        Sample, SamsungSPF, serdisplib, ShuttleVFD, SimpleLCD, st2205, T6963,]
      7 -  [                        TeakLCM, Trefon, ULA200, USBHUB, USBLCD, VNC, WincorNixdorf, X11],
      8 +  [                        TeakLCM, TEW673GRU, Trefon, ULA200, USBHUB, USBLCD, VNC, WincorNixdorf, X11],
      9    drivers=$withval,
     10    drivers=all
     11  )
     12 @@ -107,6 +107,7 @@ for driver in $drivers; do
     13  	 SHUTTLEVFD="yes"
     14           SIMPLELCD="yes"
     15           T6963="yes"
     16 +         TEW673GRU="yes"
     17           TeakLCM="yes"
     18           Trefon="yes"
     19           ULA200="yes"
     20 @@ -260,6 +261,9 @@ for driver in $drivers; do
     21        TeakLCM)
     22           TeakLCM=$val
     23           ;;
     24 +      TEW673GRU)
     25 +         TEW673GRU=$val
     26 +         ;;
     27        Trefon)
     28           Trefon=$val
     29           ;;
     30 @@ -797,6 +801,18 @@ if test "$TeakLCM" = "yes"; then
     31     AC_DEFINE(WITH_TEAK_LCM,1,[TeakLCM driver])
     32  fi
     33  
     34 +if test "$TEW673GRU" = "yes"; then
     35 +   if test "$has_spidev" = "true"; then
     36 +      GRAPHIC="yes"
     37 +      TEXT="yes"
     38 +      SPIDEV="yes"
     39 +      DRIVERS="$DRIVERS drv_TEW673GRU.o"
     40 +      AC_DEFINE(WITH_TEW673GRU,1,[TEW673GRU driver])
     41 +   else
     42 +      AC_MSG_WARN(linux/spi/spidev.h not found: TEW673GRU driver disabled)
     43 +   fi
     44 +fi
     45 +
     46  if test "$Trefon" = "yes"; then
     47     if test "$has_usb" = "true"; then
     48        TEXT="yes"
     49 --- a/drv.c
     50 +++ b/drv.c
     51 @@ -92,6 +92,7 @@ extern DRIVER drv_serdisplib;
     52  extern DRIVER drv_ShuttleVFD;
     53  extern DRIVER drv_SimpleLCD;
     54  extern DRIVER drv_T6963;
     55 +extern DRIVER drv_TEW673GRU;
     56  extern DRIVER drv_TeakLCM;
     57  extern DRIVER drv_Trefon;
     58  extern DRIVER drv_ula200;
     59 @@ -248,6 +249,9 @@ DRIVER *Driver[] = {
     60  #ifdef WITH_TEAK_LCM
     61      &drv_TeakLCM,
     62  #endif
     63 +#ifdef WITH_TEW673GRU
     64 +    &drv_TEW673GRU,
     65 +#endif
     66  #ifdef WITH_TREFON
     67      &drv_Trefon,
     68  #endif
     69 --- a/Makefile.am
     70 +++ b/Makefile.am
     71 @@ -119,6 +119,7 @@ drv_ShuttleVFD.c              \
     72  drv_SimpleLCD.c               \
     73  drv_T6963.c                   \
     74  drv_TeakLCM.c                 \
     75 +drv_TEW673GRU.c               \
     76  drv_Trefon.c                  \
     77  drv_ula200.c                  \
     78  drv_USBHUB.c                  \
     79 --- /dev/null
     80 +++ b/drv_TEW673GRU.c
     81 @@ -0,0 +1,457 @@
     82 +/* $Id$
     83 + * $URL$
     84 + *
     85 + * TRENDnet TEW673GRU LCD4linux driver
     86 + *
     87 + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
     88 + *
     89 + * based on the Sample driver which is:
     90 + * Copyright (C) 2005 Michael Reinelt <michael@reinelt.co.at>
     91 + * Copyright (C) 2005, 2006, 2007 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
     92 + *
     93 + * This file is part of LCD4Linux.
     94 + *
     95 + * LCD4Linux is free software; you can redistribute it and/or modify
     96 + * it under the terms of the GNU General Public License as published by
     97 + * the Free Software Foundation; either version 2, or (at your option)
     98 + * any later version.
     99 + *
    100 + * LCD4Linux is distributed in the hope that it will be useful,
    101 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    102 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    103 + * GNU General Public License for more details.
    104 + *
    105 + * You should have received a copy of the GNU General Public License
    106 + * along with this program; if not, write to the Free Software
    107 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    108 + *
    109 + */
    110 +
    111 +/*
    112 + * exported fuctions:
    113 + *
    114 + * struct DRIVER drv_TEW673GRU
    115 + */
    116 +
    117 +#include "config.h"
    118 +
    119 +#include <stdlib.h>
    120 +#include <stdio.h>
    121 +#include <unistd.h>
    122 +#include <string.h>
    123 +#include <errno.h>
    124 +
    125 +#include "debug.h"
    126 +#include "cfg.h"
    127 +#include "qprintf.h"
    128 +#include "udelay.h"
    129 +#include "plugin.h"
    130 +#include "widget.h"
    131 +#include "widget_text.h"
    132 +#include "widget_icon.h"
    133 +#include "widget_bar.h"
    134 +#include "drv.h"
    135 +
    136 +#include "drv_generic_text.h"
    137 +#include "drv_generic_graphic.h"
    138 +#include "drv_generic_spidev.h"
    139 +
    140 +#ifdef WITH_DMALLOC
    141 +#include <dmalloc.h>
    142 +#endif
    143 +
    144 +#define TEW673GRU_NUM_COLS	220
    145 +#define TEW673GRU_NUM_ROWS	176
    146 +#define TEW673GRU_BPP		2	/* bytes per pixel */
    147 +
    148 +#define TEW673GRU_CMD_SIZE	9
    149 +#define TEW673GRU_NUM_ROW_BYTES (TEW673GRU_NUM_COLS * TEW673GRU_BPP)
    150 +
    151 +enum {
    152 +	CMD_SHOW_STRING		= 49,
    153 +	CMD_SHOW_IMAGE_DIR	= 52,
    154 +	CMD_SCREEN_COLOR	= 54,
    155 +};
    156 +
    157 +static char Name[] = "TEW673GRU";
    158 +
    159 +static char *drv_TEW673GRU_FB;
    160 +static long FB_SIZE;
    161 +static int MODE;
    162 +
    163 +static unsigned int RGBAto16(RGBA rgb)
    164 +{
    165 +    return (((rgb.R >> 3) << 11) | ((rgb.G >> 2) << 5) | (rgb.B >> 3));
    166 +}
    167 +
    168 +static unsigned char color_msb(unsigned int color)
    169 +{
    170 +    return color >> 8;
    171 +}
    172 +
    173 +static unsigned char color_lsb(unsigned int color)
    174 +{
    175 +    return color & 0xff;
    176 +}
    177 +
    178 +static void drv_TEW673GRU_hw_clear(const unsigned int color)
    179 +{
    180 +    unsigned char cmd[TEW673GRU_CMD_SIZE];
    181 +    struct spi_ioc_transfer tr[1];
    182 +
    183 +    memset(tr, '\0', sizeof(tr));
    184 +    memset(cmd, '\0', sizeof(cmd));
    185 +
    186 +    cmd[0] = CMD_SCREEN_COLOR;
    187 +    cmd[7] = color_msb(color);
    188 +    cmd[8] = color_lsb(color);
    189 +
    190 +    tr[0].tx_buf = (unsigned long) cmd;
    191 +    tr[0].len = sizeof(cmd);
    192 +
    193 +    drv_generic_spidev_transfer(1, tr);
    194 +}
    195 +
    196 +static void drv_TEW673GRU_hw_send_row(const int row, const int col, const char *data, const int width)
    197 +{
    198 +    unsigned char cmd[TEW673GRU_CMD_SIZE];
    199 +    struct spi_ioc_transfer tr[2];
    200 +    int datasize;
    201 +
    202 +    memset(tr, '\0', sizeof(tr));
    203 +    memset(cmd, '\0', sizeof(cmd));
    204 +
    205 +    datasize =  width * TEW673GRU_BPP;
    206 +
    207 +    cmd[0] = CMD_SHOW_IMAGE_DIR;
    208 +    cmd[1] = col;
    209 +    cmd[2] = col + width;
    210 +    cmd[3] = row;
    211 +    cmd[4] = row;
    212 +    cmd[5] = datasize >> 8;
    213 +    cmd[6] = datasize & 0xff;
    214 +
    215 +    tr[0].tx_buf = (unsigned long) cmd;
    216 +    tr[0].len = sizeof(cmd);
    217 +    tr[1].tx_buf = (unsigned long) data;
    218 +    tr[1].len = datasize;
    219 +
    220 +    drv_generic_spidev_transfer(2, tr);
    221 +}
    222 +
    223 +static void drv_TEW673GRU_hw_write_string(const int row, const int col, const char *data, const int datasize)
    224 +{
    225 +    unsigned char cmd[TEW673GRU_CMD_SIZE];
    226 +    struct spi_ioc_transfer tr[2];
    227 +    unsigned char len;
    228 +
    229 +    memset(tr, '\0', sizeof(tr));
    230 +    memset(cmd, '\0', sizeof(cmd));
    231 +
    232 +    len = datasize & 0xff;
    233 +    cmd[0] = CMD_SHOW_STRING;
    234 +    cmd[1] = col;
    235 +    cmd[2] = col + (XRES * len);
    236 +    cmd[3] = row;
    237 +    cmd[4] = row + YRES;
    238 +    cmd[7] = 0;
    239 +    cmd[8] = len;
    240 +
    241 +    tr[0].tx_buf = (unsigned long) cmd;
    242 +    tr[0].len = sizeof(cmd);
    243 +    tr[1].tx_buf = (unsigned long) data;
    244 +    tr[1].len = datasize;
    245 +
    246 +    drv_generic_spidev_transfer(2, tr);
    247 +}
    248 +
    249 +static void drv_TEW673GRU_FB_set_pixel(const int col, const unsigned int color)
    250 +{
    251 +    int pos;
    252 +
    253 +    pos = col * TEW673GRU_BPP;
    254 +    drv_TEW673GRU_FB[pos] = color_msb(color);
    255 +    drv_TEW673GRU_FB[pos + 1] = color_lsb(color);
    256 +}
    257 +
    258 +static void drv_TEW673GRU_blit(const int row, const int col, const int height, const int width)
    259 +{
    260 +    int r, c;
    261 +
    262 +    debug("%s: update area r:%d c:%d w:%d h:%d", Name, row, col, height, width);
    263 +
    264 +    for (r = row; r < row + height; r++) {
    265 +	for (c = col; c < col + width; c++) {
    266 +	    unsigned int color;
    267 +	    RGBA rgb;
    268 +
    269 +	    rgb = drv_generic_graphic_rgb(r, c);
    270 +	    color = RGBAto16(rgb);
    271 +            drv_TEW673GRU_FB_set_pixel(c, color);
    272 +	}
    273 +
    274 +	if (width) {
    275 +	    char *data;
    276 +
    277 +	    data = &drv_TEW673GRU_FB[col * TEW673GRU_BPP];
    278 +	    drv_TEW673GRU_hw_send_row(r, col, data, width);
    279 +	    udelay(100 + width * 50);
    280 +	}
    281 +    }
    282 +}
    283 +
    284 +static void drv_TEW673GRU_clear(RGBA rgba)
    285 +{
    286 +    unsigned int color;
    287 +
    288 +    color = RGBAto16(rgba);
    289 +    drv_TEW673GRU_hw_clear(color);
    290 +}
    291 +
    292 +static void drv_TEW673GRU_write(const int row, const int col, const char *data, const int len)
    293 +{
    294 +    int i;
    295 +
    296 +    for (i = 0; i < len; i++) {
    297 +	drv_TEW673GRU_hw_write_string(row * YRES, (col + i) * XRES, " ", 1);
    298 +	udelay(10000);
    299 +	drv_TEW673GRU_hw_write_string(row * YRES, 2 + (col + i) * XRES, " ", 1);
    300 +	udelay(10000);
    301 +	drv_TEW673GRU_hw_write_string(row * YRES, (col + i) * XRES, &data[i], 1);
    302 +	udelay(10000);
    303 +    }
    304 +}
    305 +
    306 +static int drv_TEW673GRU_open(const char *section)
    307 +{
    308 +    int err;
    309 +
    310 +    err = drv_generic_spidev_open(section, Name);
    311 +    if (err < 0)
    312 +	return err;
    313 +
    314 +    return 0;
    315 +}
    316 +
    317 +static int drv_TEW673GRU_close(void)
    318 +{
    319 +    drv_generic_spidev_close();
    320 +    return 0;
    321 +}
    322 +
    323 +static void drv_TEW673GRU_clear_screen(void)
    324 +{
    325 +    if (MODE) {
    326 +	drv_generic_graphic_clear();
    327 +    } else {
    328 +	memset(drv_TEW673GRU_FB, ' ', FB_SIZE);
    329 +	drv_TEW673GRU_hw_clear(0x0000);
    330 +    }
    331 +}
    332 +
    333 +static int drv_TEW673GRU_init_font(const char *section)
    334 +{
    335 +    char *font;
    336 +    int ret = -1;
    337 +
    338 +    font = cfg_get(section, "Font", "6x8");
    339 +    if (font == NULL) {
    340 +	error("%s: no '%s.Font' entry from %s", Name, section, cfg_source());
    341 +	goto out;
    342 +    }
    343 +
    344 +    if (*font == '\0') {
    345 +	error("%s: invalid '%s.Font' entry in %s", Name, section, cfg_source());
    346 +	goto out_free;
    347 +    }
    348 +
    349 +    XRES = -1;
    350 +    YRES = -1;
    351 +    if (sscanf(font, "%dx%d", &XRES, &YRES) != 2 ||
    352 +	XRES < 1 ||
    353 +	YRES < 1) {
    354 +	error("%s: bad Font '%s' from %s", Name, font, cfg_source());
    355 +	goto out_free;
    356 +    }
    357 +
    358 +    if (XRES != 6 && YRES != 8) {
    359 +	error("%s: bad Font '%s' from %s (only 6x8 at the moment)",
    360 +	      Name, font, cfg_source());
    361 +	goto out_free;
    362 +    }
    363 +
    364 +    error("%s: font '%s' selected", Name, font);
    365 +
    366 +    ret = 0;
    367 +
    368 +out_free:
    369 +    free(font);
    370 +out:
    371 +    return ret;
    372 +}
    373 +
    374 +static int drv_TEW673GRU_start(const char *section)
    375 +{
    376 +    int ret;
    377 +
    378 +    DCOLS = TEW673GRU_NUM_COLS;
    379 +    DROWS = TEW673GRU_NUM_ROWS;
    380 +
    381 +    if (MODE) {
    382 +	ret = drv_TEW673GRU_init_font(section);
    383 +	if (ret)
    384 +	    goto err;
    385 +
    386 +	FB_SIZE = DCOLS * TEW673GRU_BPP;
    387 +    } else {
    388 +	XRES = 10;
    389 +	YRES = 16;
    390 +	DCOLS = DCOLS / XRES;
    391 +	DROWS = DROWS / YRES;
    392 +
    393 +	FB_SIZE = DCOLS * DROWS;
    394 +    }
    395 +
    396 +    if (FB_SIZE) {
    397 +	drv_TEW673GRU_FB = malloc(FB_SIZE);
    398 +	if (drv_TEW673GRU_FB == NULL) {
    399 +	    error("%s: framebuffer could not be allocated", Name);
    400 +	    goto err;
    401 +	}
    402 +    }
    403 +
    404 +    ret = drv_TEW673GRU_open(section);
    405 +    if (ret < 0)
    406 +        goto err_free;
    407 +
    408 +    if (MODE == 0)
    409 +    	drv_TEW673GRU_clear_screen();
    410 +
    411 +    return 0;
    412 +
    413 + err_free:
    414 +    if (drv_TEW673GRU_FB)
    415 +	free(drv_TEW673GRU_FB);
    416 + err:
    417 +    return -1;
    418 +}
    419 +
    420 +static int drv_TEW673GRU_greet(const char *msg1, const char *msg2)
    421 +{
    422 +    if (MODE)
    423 +	return drv_generic_graphic_greet(msg1, msg2);
    424 +
    425 +    return drv_generic_text_greet(msg1, msg2);
    426 +}
    427 +
    428 +
    429 +/****************************************/
    430 +/***        widget callbacks          ***/
    431 +/****************************************/
    432 +
    433 +
    434 +/* using drv_generic_text_draw(W) */
    435 +/* using drv_generic_text_icon_draw(W) */
    436 +/* using drv_generic_text_bar_draw(W) */
    437 +/* using drv_generic_gpio_draw(W) */
    438 +
    439 +
    440 +/****************************************/
    441 +/***        exported functions        ***/
    442 +/****************************************/
    443 +
    444 +int drv_TEW673GRU_list(void)
    445 +{
    446 +    printf("TEW673GRU driver");
    447 +    return 0;
    448 +}
    449 +
    450 +int drv_TEW673GRU_init(const char *section, const int quiet)
    451 +{
    452 +    WIDGET_CLASS wc;
    453 +    int ret;
    454 +
    455 +    cfg_number(section, "Mode", 0, 0, 1, &MODE);
    456 +
    457 +    if (MODE) {
    458 +	drv_generic_graphic_real_blit = drv_TEW673GRU_blit;
    459 +	drv_generic_graphic_real_clear = drv_TEW673GRU_clear;
    460 +    } else {
    461 +	drv_generic_text_real_write = drv_TEW673GRU_write;
    462 +    }
    463 +
    464 +    ret = drv_TEW673GRU_start(section);
    465 +    if (ret)
    466 +	return ret;
    467 +
    468 +    if (MODE) {
    469 +	ret = drv_generic_graphic_init(section, Name);
    470 +	if (ret)
    471 +	    return ret;
    472 +    } else {
    473 +	ret = drv_generic_text_init(section, Name);
    474 +	if (ret)
    475 +	    return ret;
    476 +
    477 +	ret = drv_generic_text_icon_init();
    478 +	if (ret != 0)
    479 +	    return ret;
    480 +
    481 +	ret = drv_generic_text_bar_init(1);
    482 +	if (ret != 0)
    483 +	    return ret;
    484 +
    485 +	drv_generic_text_bar_add_segment(0, 0, 255, ' ');
    486 +	drv_generic_text_bar_add_segment(255, 255, 255, '#');
    487 +
    488 +	wc = Widget_Text;
    489 +	wc.draw = drv_generic_text_draw;
    490 +	widget_register(&wc);
    491 +
    492 +	wc = Widget_Icon;
    493 +	wc.draw = drv_generic_text_icon_draw;
    494 +	widget_register(&wc);
    495 +
    496 +	wc = Widget_Bar;
    497 +	wc.draw = drv_generic_text_bar_draw;
    498 +	widget_register(&wc);
    499 +    }
    500 +
    501 +    if (!quiet) {
    502 +	char buffer[40];
    503 +	qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
    504 +	drv_TEW673GRU_greet(buffer, "www.openwrt.org");
    505 +	sleep(3);
    506 +	drv_TEW673GRU_clear_screen();
    507 +    }
    508 +
    509 +    return 0;
    510 +}
    511 +
    512 +int drv_TEW673GRU_quit(const int quiet)
    513 +{
    514 +
    515 +    info("%s: shutting down.", Name);
    516 +
    517 +    drv_TEW673GRU_clear_screen();
    518 +
    519 +    if (!quiet)
    520 +	drv_TEW673GRU_greet("goodbye!", NULL);
    521 +
    522 +    if (MODE)
    523 +	drv_generic_graphic_quit();
    524 +    else
    525 +	drv_generic_text_quit();
    526 +
    527 +    debug("closing connection");
    528 +    drv_TEW673GRU_close();
    529 +
    530 +    return (0);
    531 +}
    532 +
    533 +DRIVER drv_TEW673GRU = {
    534 +    .name = Name,
    535 +    .list = drv_TEW673GRU_list,
    536 +    .init = drv_TEW673GRU_init,
    537 +    .quit = drv_TEW673GRU_quit,
    538 +};
    539 --- a/lcd4linux.conf.sample
    540 +++ b/lcd4linux.conf.sample
    541 @@ -581,6 +581,11 @@ Display FutabaVFD {
    542      }
    543  }
    544  
    545 +Display TEW673GRU {
    546 +    Driver       'TEW673GRU'
    547 +    Font         '6x8'
    548 +    Port         '/dev/spidev1.0'
    549 +}
    550  
    551  #Plugin KVV {
    552  #    StationID '12_701'