summaryrefslogtreecommitdiffstats
path: root/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src
diff options
context:
space:
mode:
Diffstat (limited to 'meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src')
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/Makefile13
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.c236
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.h66
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.c107
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.h42
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/mdio_bb.c336
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/spi_bb.c317
7 files changed, 0 insertions, 1117 deletions
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/Makefile b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/Makefile
deleted file mode 100644
index 102ac4e..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2014-present Facebook. All Rights Reserved.
-all: spi-bb mdio-bb
-
-spi-bb: spi_bb.o bitbang.o gpio.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-mdio-bb: mdio_bb.o bitbang.o gpio.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-.PHONY: clean
-
-clean:
- rm -rf *.o spi-bb mdio-bb
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.c b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.c
deleted file mode 100644
index cf7dcd3..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-//#define DEBUG
-//#define VERBOSE
-
-#include "bitbang.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "facebook/log.h"
-
-#define NANOSEC_IN_SEC (1000 * 1000 * 1000)
-
-#define BITBANG_FREQ_MAX (500 * 1000 * 1000) /* 500M Hz */
-#define BITBANG_FREQ_DEFAULT (1 * 1000 * 1000) /* 1M Hz */
-
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-struct bitbang_handle {
- bitbang_init_st bbh_init;
- uint32_t bbh_half_clk; /* ns per clock cycle */
-};
-
-void bitbang_init_default(bitbang_init_st *init)
-{
- memset(init, sizeof(*init), 0);
- init->bbi_clk_start = BITBANG_PIN_HIGH;
- init->bbi_data_out = BITBANG_CLK_EDGE_FALLING;
- init->bbi_data_in = BITBANG_CLK_EDGE_RISING;
- init->bbi_freq = BITBANG_FREQ_DEFAULT;
-}
-
-bitbang_handle_st* bitbang_open(const bitbang_init_st *init)
-{
- bitbang_handle_st *hdl;
-
- if (!init || !init->bbi_pin_f
- || !init->bbi_freq || init->bbi_freq > BITBANG_FREQ_MAX) {
- LOG_ERR(EINVAL, "Invalid init structure");
- return NULL;
- }
-
- hdl = calloc(1, sizeof(*hdl));
- if (!hdl) {
- return NULL;
- }
-
- hdl->bbh_init = *init;
- hdl->bbh_half_clk = NANOSEC_IN_SEC / init->bbi_freq / 2;
-
- LOG_DBG("Bitbang open with initial %s, data out at %s, data in at %s, "
- "freq at %uHz, half clk %uns",
- (init->bbi_clk_start == BITBANG_PIN_LOW) ? "LOW" : "HIGH",
- (init->bbi_data_out == BITBANG_CLK_EDGE_RISING)
- ? "RISING" : "FALLING",
- (init->bbi_data_in == BITBANG_CLK_EDGE_RISING)
- ? "RISING" : "FALLING",
- init->bbi_freq, hdl->bbh_half_clk);
-
- return hdl;
-}
-
-void bitbang_close(bitbang_handle_st *hdl)
-{
- free(hdl);
-}
-
-/*
- * The threshold (ns) to use spin instead of nanosleep().
- * Before adding the high resolution timer support, either spin or nanosleep()
- * will not bring the process wakeup within 10ms. It turns out the system time
- * update is also controlled by HZ (100).
- * After I added the high resolution timer support, the spin works as the
- * system time is updated more frequently. However, nanosleep() solution is
- * still noticable slower comparing with spin. There could be some kernel
- * scheduling tweak missing. Did not get time on that yet.
- * For now, use 10ms as the threshold to determine if spin or nanosleep()
- * is used.
- */
-#define BITBANG_SPIN_THRESHOLD (10 * 1000 * 1000)
-
-static int sleep_ns(uint32_t clk)
-{
- struct timespec req, rem;
- int rc = 0;
- if (clk <= BITBANG_SPIN_THRESHOLD) {
- struct timespec orig;
- rc = clock_gettime(CLOCK_MONOTONIC, &req);
- orig = req;
- while (!rc && clk) {
- uint32_t tmp;
- rc = clock_gettime(CLOCK_MONOTONIC, &rem);
- tmp = (rem.tv_sec - req.tv_sec) * NANOSEC_IN_SEC;
- if (rem.tv_nsec >= req.tv_nsec) {
- tmp += rem.tv_nsec - req.tv_nsec;
- } else {
- tmp -= req.tv_nsec - rem.tv_nsec;
- }
- if (tmp >= clk) {
- break;
- }
- clk -= tmp;
- req = rem;
- }
- } else {
- req.tv_sec = 0;
- req.tv_nsec = clk;
- while ((rc = nanosleep(&req, &rem)) == -1 && errno == EINTR) {
- req = rem;
- }
- }
- if (rc == -1) {
- rc = errno;
- LOG_ERR(rc, "Failed to sleep %u nanoseconds", clk);
- }
- return rc;
-}
-
-int bitbang_io(const bitbang_handle_st *hdl, bitbang_io_st *io)
-{
- int rc = 0;
- uint32_t clk = hdl->bbh_half_clk;
- const struct {
- bitbang_pin_value_en value;
- bitbang_clk_edge_en edge;
- } clks[] = {
- {BITBANG_PIN_HIGH, BITBANG_CLK_EDGE_FALLING},
- {BITBANG_PIN_LOW, BITBANG_CLK_EDGE_RISING},
- };
- int clk_idx;
- int n_clk = 0;
- int n_bits = 0;
- const uint8_t *dout = io->bbio_dout;
- uint8_t *din = io->bbio_din;
- int bit_pos = 7;
- bitbang_pin_func pin_f = hdl->bbh_init.bbi_pin_f;
- void *context = hdl->bbh_init.bbi_context;
-
- if ((io->bbio_in_bits == 0 && io->bbio_din)
- || (io->bbio_in_bits > 0 && !io->bbio_din)) {
- rc = EINVAL;
- LOG_ERR(rc, "Incorrect in bits and in buffer");
- goto out;
- }
-
- if ((io->bbio_out_bits == 0 && io->bbio_dout)
- || (io->bbio_out_bits > 0 && !io->bbio_dout)) {
- rc = EINVAL;
- LOG_ERR(rc, "Incorrect out bits and out buffer");
- goto out;
- }
-
- if (io->bbio_in_bits == 0 && io->bbio_out_bits == 0) {
- rc = EINVAL;
- LOG_ERR(rc, "Both in and out bits are 0");
- goto out;
- }
-
- if (hdl->bbh_init.bbi_clk_start == BITBANG_PIN_HIGH) {
- clk_idx = 0;
- } else {
- clk_idx = 1;
- }
-
- /* set the CLK pin start position */
- pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context);
-
- /* clear the first byte of din */
- if (din && io->bbio_in_bits) {
- memset(din, 0, (io->bbio_in_bits + 7) / 8);
- }
-
- do {
- if ((rc = sleep_ns(clk))) {
- goto out;
- }
-
- /* output first */
- if (hdl->bbh_init.bbi_data_out == clks[clk_idx].edge) {
- if (dout && n_bits < io->bbio_out_bits) {
- pin_f(BITBANG_DATA_OUT, (*dout >> bit_pos) & 0x1, context);
- }
- }
-
- /* then, input */
- if (hdl->bbh_init.bbi_data_in == clks[clk_idx].edge) {
- if (din && n_bits < io->bbio_in_bits) {
- *din |= (pin_f(BITBANG_DATA_IN, 0, context) & 0x1) << bit_pos;
- }
- }
-
- if (++n_clk % 2 == 0) {
- /* one bit for every 2 half clks */
- n_bits ++;
- if (bit_pos == 0) {
- if (dout) {
- dout++;
- }
- if (din) {
- din++;
- }
- bit_pos = 7;
- } else {
- bit_pos --;
- }
- }
- clk_idx = 1 - clk_idx;
- pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context);
- } while (n_bits < MAX(io->bbio_in_bits, io->bbio_out_bits));
-
- out:
-
- return -rc;
-}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.h b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.h
deleted file mode 100644
index 0f21a49..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/bitbang.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef BITBANG_H
-#define BITBANG_H
-
-#include <stdint.h>
-
-typedef enum {
- BITBANG_CLK_PIN,
- BITBANG_DATA_IN,
- BITBANG_DATA_OUT,
-} bitbang_pin_type_en;
-
-typedef enum {
- BITBANG_PIN_LOW = 0,
- BITBANG_PIN_HIGH = 1,
-} bitbang_pin_value_en;
-
-typedef enum {
- BITBANG_CLK_EDGE_RISING,
- BITBANG_CLK_EDGE_FALLING,
-} bitbang_clk_edge_en;
-
-typedef bitbang_pin_value_en (* bitbang_pin_func)(
- bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context);
-
-typedef struct {
- bitbang_pin_value_en bbi_clk_start;
- bitbang_clk_edge_en bbi_data_out;
- bitbang_clk_edge_en bbi_data_in;
- uint32_t bbi_freq;
- bitbang_pin_func bbi_pin_f;
- void *bbi_context;
-} bitbang_init_st;
-
-typedef struct bitbang_handle bitbang_handle_st;
-
-void bitbang_init_default(bitbang_init_st *init);
-bitbang_handle_st* bitbang_open(const bitbang_init_st *init);
-void bitbang_close(bitbang_handle_st *hdl);
-
-typedef struct {
- uint32_t bbio_in_bits;
- uint32_t bbio_out_bits;
- uint8_t *bbio_dout;
- uint8_t *bbio_din;
-} bitbang_io_st;
-
-int bitbang_io(const bitbang_handle_st *hdl, bitbang_io_st *io);
-
-#endif
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.c b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.c
deleted file mode 100644
index 026aebc..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-//#define DEBUG
-//#define VERBOSE
-
-#include "gpio.h"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-
-#include "facebook/log.h"
-
-void gpio_init_default(gpio_st *g) {
- g->gs_gpio = -1;
- g->gs_fd = -1;
-}
-
-int gpio_open(gpio_st *g, int gpio)
-{
- char buf[128];
- int rc;
-
- snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/value", gpio);
- rc = open(buf, O_RDWR);
- if (rc == -1) {
- rc = errno;
- LOG_ERR(rc, "Failed to open %s", buf);
- return -rc;
- }
- g->gs_fd = rc;
- g->gs_gpio = gpio;
- return 0;
-}
-
-void gpio_close(gpio_st *g)
-{
- if (g && g->gs_fd != -1) {
- close(g->gs_fd);
- }
- gpio_init_default(g);
-}
-
-gpio_value_en gpio_read(gpio_st *g)
-{
- char buf[32] = {0};
- gpio_value_en v;
- lseek(g->gs_fd, 0, SEEK_SET);
- read(g->gs_fd, buf, sizeof(buf));
- v = atoi(buf) ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW;
- LOG_VER("read gpio=%d value=%d %d", g->gs_gpio, atoi(buf), v);
- return v;
-}
-
-void gpio_write(gpio_st *g, gpio_value_en v)
-{
- lseek(g->gs_fd, 0, SEEK_SET);
- write(g->gs_fd, (v == GPIO_VALUE_HIGH) ? "1" : "0", 1);
- LOG_VER("write gpio=%d value=%d", g->gs_gpio, v);
-}
-
-int gpio_change_direction(gpio_st *g, gpio_direction_en dir)
-{
- char buf[128];
- char *val;
- int fd = -1;
- int rc = 0;
-
- snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", g->gs_gpio);
- fd = open(buf, O_WRONLY);
- if (fd == -1) {
- rc = errno;
- LOG_ERR(rc, "Failed to open %s", buf);
- return -rc;
- }
-
- val = (dir == GPIO_DIRECTION_IN) ? "in" : "out";
- write(fd, val, strlen(val));
-
- LOG_VER("change gpio=%d direction=%s", g->gs_gpio, val);
-
- out:
- if (fd != -1) {
- close(fd);
- }
- return -rc;
-}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.h b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.h
deleted file mode 100644
index 3303986..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/gpio.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef GPIO_H
-#define GPIO_H
-
-typedef struct {
- int gs_gpio;
- int gs_fd;
-} gpio_st;
-
-typedef enum {
- GPIO_DIRECTION_IN,
- GPIO_DIRECTION_OUT,
-} gpio_direction_en;
-
-typedef enum {
- GPIO_VALUE_LOW = 0,
- GPIO_VALUE_HIGH = 1,
-} gpio_value_en;
-
-int gpio_open(gpio_st* g, int gpio);
-void gpio_close(gpio_st *g);
-gpio_value_en gpio_read(gpio_st *g);
-void gpio_write(gpio_st *g, gpio_value_en v);
-int gpio_change_direction(gpio_st *g, gpio_direction_en dir);
-
-#endif
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/mdio_bb.c b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/mdio_bb.c
deleted file mode 100644
index ef0c567..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/mdio_bb.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-//#define DEBUG
-//#define VERBOSE
-
-#include "bitbang.h"
-#include "gpio.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "facebook/log.h"
-
-
-typedef struct {
- gpio_st m_mdc;
- gpio_st m_mdio;
-} mdio_context_st;
-
-/*
- * 32b preamble, 2b start of frame, 2b operation code,
- * 5b phy addr, 5b register addr, 2b turnaround, 16b data
- */
-#define N_BITS (32 + 2 + 2 + 5 + 5 + 2 + 16)
-#define N_BYTES (N_BITS + 7 / 8)
-
-#define START_OF_FRAME 0x1
-#define OP_READ 0x2
-#define OP_WRITE 0x1
-#define TURNAROUND 0x2 /* TA for write, for read, phy sends out TA */
-
-void usage()
-{
- fprintf(stderr,
- "Usage:\n"
- "mdio-bb: -c <GPIO for MDC> [-C <HIGH|low>]\n"
- " -d <GPIO for MDIO> [-O <rising|FALLING>]\n"
- " [-I <RISING|falling>] [-p] [-b]\n"
- " <read|write> <phy address> <register address>\n"
- " [value to write]\n");
-}
-
-bitbang_pin_value_en mdio_pin_f(
- bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context)
-{
- mdio_context_st *ctx = (mdio_context_st *)context;
- gpio_st *gpio;
- bitbang_pin_value_en res;
-
- switch (pin) {
- case BITBANG_CLK_PIN:
- gpio = &ctx->m_mdc;
- break;
- case BITBANG_DATA_IN:
- case BITBANG_DATA_OUT:
- gpio = &ctx->m_mdio;
- break;
- }
- if (pin == BITBANG_DATA_IN) {
- res = gpio_read(gpio) ? BITBANG_PIN_HIGH : BITBANG_PIN_LOW;
- } else {
- res = value;
- gpio_write(gpio, ((res == BITBANG_PIN_HIGH)
- ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
- }
- return res;
-}
-
-int main(int argc, char* const argv[])
-{
- int opt;
- int mdc = -1, mdio = -1;
- bitbang_pin_value_en mdc_start = BITBANG_PIN_HIGH;
- bitbang_clk_edge_en out_edge = BITBANG_CLK_EDGE_FALLING;
- bitbang_clk_edge_en in_edge = BITBANG_CLK_EDGE_RISING;
- int is_write;
- uint32_t phy_addr;
- uint32_t reg_addr;
- uint32_t data; /* data to write/read*/
- uint8_t buf[N_BYTES];
- uint8_t *buf_p;
- mdio_context_st ctx;
- bitbang_init_st init;
- bitbang_handle_st *hdl = NULL;
- bitbang_io_st io;
- int n_bits;
- int i;
- int rc = 0;
- int preamble = 0;
- int binary = 0;
-
- while ((opt = getopt(argc, argv, "bc:C:d:D:p")) != -1) {
- switch (opt) {
- case 'b':
- binary = 1;
- break;
- case 'c':
- mdc = atoi(optarg);
- break;
- case 'C':
- if (!strcasecmp(optarg, "high")) {
- mdc_start = BITBANG_PIN_HIGH;
- } else if (!strcasecmp(optarg, "low")) {
- mdc_start = BITBANG_PIN_LOW;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'd':
- mdio = atoi(optarg);
- break;
- case 'I':
- if (!strcasecmp(optarg, "rising")) {
- in_edge = BITBANG_CLK_EDGE_RISING;
- } if (!strcasecmp(optarg, "falling")) {
- in_edge = BITBANG_CLK_EDGE_FALLING;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'O':
- if (!strcasecmp(optarg, "rising")) {
- out_edge = BITBANG_CLK_EDGE_RISING;
- } if (!strcasecmp(optarg, "falling")) {
- out_edge = BITBANG_CLK_EDGE_FALLING;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'p':
- preamble = 1;
- break;
- default:
- usage();
- exit(-1);
- }
- }
-
- if (mdc < 0 || mdio < 0) {
- usage();
- exit(-1);
- }
-
- if (optind + 2 >= argc) {
- usage();
- exit(-1);
- }
-
- /* read or write */
- if (!strcasecmp(argv[optind], "read")) {
- is_write = 0;
- } else if (!strcasecmp(argv[optind], "write")) {
- is_write = 1;
- } else {
- usage();
- exit(-1);
- }
-
- /* phy address, 5 bits only, so must be <= 0x1f */
- phy_addr = strtoul(argv[optind + 1], NULL, 0);
- if (phy_addr > 0x1f) {
- usage();
- exit(-1);
- }
-
- /* register address, 5 bits only, so must be <= 0x1f */
- reg_addr = strtoul(argv[optind + 2], NULL, 0);
- if (reg_addr > 0x1f) {
- usage();
- exit(-1);
- }
-
- /* data */
- if (is_write) {
- if ((!binary && (optind + 4 != argc)) ||
- (binary && (optind + 3 != argc))) {
- usage();
- exit(-1);
- }
- if (binary) {
- uint16_t temp = 0;
- if (fread(&temp, sizeof(temp), 1, stdin) != 1) {
- usage();
- exit(-1);
- }
- data = htons(temp);
- } else {
- data = strtoul(argv[optind + 3], NULL, 0);
- }
- if (data > 0xFFFF) {
- usage();
- exit(-1);
- }
- } else {
- if ((!binary && (optind + 3 != argc)) ||
- (binary && (optind + 2 != argc))) {
- usage();
- exit(-1);
- }
- }
-
- /* open all gpio */
- memset(&ctx, sizeof(ctx), 0);
- gpio_init_default(&ctx.m_mdc);
- gpio_init_default(&ctx.m_mdio);
- if (gpio_open(&ctx.m_mdc, mdc) || gpio_open(&ctx.m_mdio, mdio)) {
- goto out;
- }
-
- if (gpio_change_direction(&ctx.m_mdc, GPIO_DIRECTION_OUT)
- || gpio_change_direction(&ctx.m_mdio, GPIO_DIRECTION_OUT)) {
- goto out;
- }
-
- bitbang_init_default(&init);
- init.bbi_clk_start = mdc_start;
- init.bbi_data_out = out_edge;
- init.bbi_data_in = in_edge;
- init.bbi_freq = 1000 * 1000; /* 1M Hz */
- init.bbi_pin_f = mdio_pin_f;
- init.bbi_context = &ctx;
- hdl = bitbang_open(&init);
- if (!hdl) {
- goto out;
- }
-
- if (is_write) {
- buf[0] = (data >> 8) & 0xFF;
- buf[1] = data & 0xFF;
- io.bbio_out_bits = 16;
- io.bbio_dout = buf;
- io.bbio_in_bits = 0;
- io.bbio_din = NULL;
- } else {
- io.bbio_in_bits = 16;
- io.bbio_din = buf;
- io.bbio_out_bits = 0;
- io.bbio_dout = NULL;
- }
-
- /* preamble, 32b */
- buf_p = buf;
- n_bits = 0;
- if (preamble) {
- /* 32 bit of 1 for preamble */
- for (i = 0; i < 4; i++) {
- *buf_p++ = 0xFF;
- }
- n_bits += 32;
- }
-
- /*
- * MDIO transaction header is:
- * 2b START, 2b OPER CODE, 5b PHY ADDR, 5b register addr, 2b TURNROUND
- */
- *buf_p++ = (START_OF_FRAME << 6) | (((is_write) ? OP_WRITE : OP_READ) << 4)
- | ((phy_addr >> 1) & 0xF);
- *buf_p++ = ((phy_addr & 0x1) << 7) | ((reg_addr & 0x1F) << 2) | TURNAROUND;
- if (is_write) {
- *buf_p++ = (data >> 8) & 0xFF;
- *buf_p++ = data & 0xFF;
- /* total # of bits is transaction header + 2 bytes to write */
- n_bits += 2 + 2 + 5 + 5 + 2 + 16;
- } else {
- /* for read, master does not send TR, so, n_bits should not include TR */
- n_bits += 2 + 2 + 5 + 5;
- }
-
- memset(&io, sizeof(io), 0);
- io.bbio_out_bits = n_bits;
- io.bbio_dout = buf;
- io.bbio_in_bits = 0;
- io.bbio_din = NULL;
-
- rc = bitbang_io(hdl, &io);
- if (rc != 0) {
- goto out;
- }
-
- /* for read, need to do another io for (2b TR + 16b data) reading */
- if (!is_write) {
- /* first, change the MDIO to input */
- gpio_change_direction(&ctx.m_mdio, GPIO_DIRECTION_IN);
- /* then, run the clock for read */
- memset(&io, sizeof(io), 0);
- io.bbio_out_bits = 0;
- io.bbio_dout = NULL;;
- io.bbio_in_bits = 18;
- io.bbio_din = buf;
-
- rc = bitbang_io(hdl, &io);
- if (rc != 0) {
- goto out;
- }
-
- data = ((buf[0] << 2) | (buf[1] >> 6)) & 0xFF;
- data <<= 8;
- data |= ((buf[1] << 2) | (buf[2] >> 6)) & 0xFF;
- }
-
- if (binary) {
- if (!is_write) {
- uint16_t temp = ntohs(data);
- fwrite(&temp, sizeof(temp), 1, stdout);
- }
- } else {
- printf("%s: 0x%02x\n", (is_write) ? "Wrote" : "Read", data);
- }
-
- out:
- if (hdl) {
- bitbang_close(hdl);
- }
- gpio_close(&ctx.m_mdc);
- gpio_close(&ctx.m_mdio);
-
- return 0;
-}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/spi_bb.c b/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/spi_bb.c
deleted file mode 100644
index ce366a5..0000000
--- a/meta-facebook/meta-wedge/recipes-wedge/bitbang/files/src/spi_bb.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2014-present Facebook. All Rights Reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-//#define DEBUG
-//#define VERBOSE
-
-#include "bitbang.h"
-#include "gpio.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "facebook/log.h"
-
-void usage()
-{
- fprintf(stderr,
- "Usage:\n"
- "spi-bb: -s <GPIO for CS> [-S <HIGH|low>]\n"
- " -c <GPIO for CLK> [-C <HIGH|low>]\n"
- " -o <GPIO for MOSI> [-O <rising|FALLING>]\n"
- " -i <GPIO for MISO> [-I <RISING|falling>]\n"
- " [-b]\n"
- " < [-r <number of bits to read>]\n"
- " [-w <number of bits to write> <byte 1> [... byte N]>\n\n"
- "Note: If both '-r' and '-w' are provided, 'write' will be performed\n"
- " before 'read'.\n");
-}
-
-typedef struct {
- gpio_st sc_clk;
- gpio_st sc_mosi;
- gpio_st sc_miso;
-} spi_context_st;
-
-bitbang_pin_value_en spi_pin_f(
- bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context)
-{
- spi_context_st *ctx = (spi_context_st *)context;
- gpio_st *gpio;
- bitbang_pin_value_en res;
-
- switch (pin) {
- case BITBANG_CLK_PIN:
- gpio = &ctx->sc_clk;
- break;
- case BITBANG_DATA_IN:
- gpio = &ctx->sc_miso;
- break;
- case BITBANG_DATA_OUT:
- gpio = &ctx->sc_mosi;
- break;
- }
- if (pin == BITBANG_DATA_IN) {
- res = gpio_read(gpio) ? BITBANG_PIN_HIGH : BITBANG_PIN_LOW;
- } else {
- res = value;
- gpio_write(gpio, ((res == BITBANG_PIN_HIGH)
- ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
- }
- return res;
-}
-
-int main(int argc, char * const argv[])
-{
- bitbang_init_st init;
- bitbang_handle_st *hdl = NULL;
- int cs = -1, clk = -1, in = -1, out = -1;
- gpio_st cs_gpio;
- int opt;
- int is_write = 0;
- int is_read = 0;
- int read_bits = 0;
- int write_bits = 0;
- int read_bytes = 0;
- int write_bytes = 0;
- int i;
- uint8_t *read_buf = NULL;;
- uint8_t *write_buf = NULL;;
- bitbang_clk_edge_en dout_edge = BITBANG_CLK_EDGE_FALLING;
- bitbang_clk_edge_en din_edge = BITBANG_CLK_EDGE_RISING;
- bitbang_pin_value_en clk_start = BITBANG_PIN_HIGH;
- bitbang_pin_value_en cs_value = BITBANG_PIN_HIGH;
- spi_context_st ctx;
- bitbang_io_st io;
- int rc = 0;
- int binary = 0;
-
- memset(&ctx, sizeof(ctx), 0);
- gpio_init_default(&ctx.sc_clk);
- gpio_init_default(&ctx.sc_mosi);
- gpio_init_default(&ctx.sc_miso);
- gpio_init_default(&cs_gpio);
-
- while ((opt = getopt(argc, argv, "bs:S:c:C:o:O:i:I:w:r:")) != -1) {
- switch (opt) {
- case 'b':
- binary = 1;
- break;
- case 's':
- cs = atoi(optarg);
- break;
- case 'S':
- if (!strcmp(optarg, "high")) {
- cs_value = BITBANG_PIN_HIGH;
- } else if (!strcmp(optarg, "low")) {
- cs_value = BITBANG_PIN_LOW;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'c':
- clk = atoi(optarg);
- break;
- case 'C':
- if (!strcasecmp(optarg, "high")) {
- clk_start = BITBANG_PIN_HIGH;
- } else if (!strcasecmp(optarg, "low")) {
- clk_start = BITBANG_PIN_LOW;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'o':
- out = atoi(optarg);
- break;
- case 'O':
- if (!strcasecmp(optarg, "rising")) {
- dout_edge = BITBANG_CLK_EDGE_RISING;
- } else if (!strcasecmp(optarg, "falling")) {
- dout_edge = BITBANG_CLK_EDGE_FALLING;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'i':
- in = atoi(optarg);
- break;
- case 'I':
- if (!strcasecmp(optarg, "rising")) {
- din_edge = BITBANG_CLK_EDGE_RISING;
- } else if (!strcasecmp(optarg, "falling")) {
- din_edge = BITBANG_CLK_EDGE_FALLING;
- } else {
- usage();
- exit(-1);
- }
- break;
- case 'w':
- is_write = 1;
- write_bits = atoi(optarg);
- if (write_bits <= 0) {
- usage();
- exit(-1);
- }
- break;
- case 'r':
- is_read = 1;
- read_bits = atoi(optarg);
- if (read_bits <= 0) {
- usage();
- exit(-1);
- }
- break;
- default:
- usage();
- exit(-1);
- }
- }
-
- if (clk < 0 || in < 0 || out < 0) {
- usage();
- exit(-1);
- }
-
- if ((!is_read && !is_write)) {
- usage();
- exit(-1);
- }
-
- write_bytes = ((write_bits + 7) / 8);
- if (write_bytes) {
- write_buf = calloc(write_bytes, sizeof(uint8_t));
- if (!write_buf) {
- goto out;
- }
- if (binary) {
- size_t written_bytes;
- written_bytes = fread(write_buf, sizeof(*write_buf), write_bytes, stdin);
- if( written_bytes != write_bytes ) {
- goto out;
- }
- } else {
- for (i = 0; i < write_bytes && i + optind < argc; i++) {
- write_buf[i] = strtoul(argv[i + optind], NULL, 0);
- }
- }
- }
-
- read_bytes = ((read_bits + 7) / 8);
- if (read_bytes) {
- read_buf = calloc(read_bytes, sizeof(uint8_t));
- if (!read_buf) {
- goto out;
- }
- }
-
- if (gpio_open(&ctx.sc_clk, clk) || gpio_open(&ctx.sc_miso, in)
- || gpio_open(&ctx.sc_mosi, out)) {
- goto out;
- }
-
- /* change GPIO directions, only MISO is input, all others are output */
- if (gpio_change_direction(&ctx.sc_clk, GPIO_DIRECTION_OUT)
- || gpio_change_direction(&ctx.sc_miso, GPIO_DIRECTION_IN)
- || gpio_change_direction(&ctx.sc_mosi, GPIO_DIRECTION_OUT)) {
- goto out;
- }
-
- if (cs != -1) {
- if (gpio_open(&cs_gpio, cs)) {
- goto out;
- }
- if (gpio_change_direction(&cs_gpio, GPIO_DIRECTION_OUT)) {
- goto out;
- }
- }
-
- bitbang_init_default(&init);
- init.bbi_clk_start = clk_start;
- init.bbi_data_out = dout_edge;
- init.bbi_data_in = din_edge;
- init.bbi_freq = 1000 * 1000; /* 1M Hz */
- init.bbi_pin_f = spi_pin_f;
- init.bbi_context = &ctx;
-
- hdl = bitbang_open(&init);
- if (!hdl) {
- goto out;
- }
-
- if (cs != -1) {
- /* have chip select */
- gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
- ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
- }
-
- memset(&io, sizeof(io), 0);
- io.bbio_in_bits = read_bits;
- io.bbio_din = read_buf;
- io.bbio_out_bits = write_bits;
- io.bbio_dout = write_buf;
-
- rc = bitbang_io(hdl, &io);
- if (rc != 0) {
- goto out;
- }
-
- if (binary) {
- fwrite(read_buf, sizeof(*read_buf), read_bytes, stdout);
- } else {
- if (write_bits) {
- printf("Wrote %u bits:", write_bits);
- for (i = 0; i < write_bytes; i++) {
- printf(" %02x", write_buf[i]);
- }
- printf("\n");
- }
-
- if (read_bits) {
- printf("Read %u bits:", read_bits);
- for (i = 0; i < read_bytes; i++) {
- printf(" %02x", read_buf[i]);
- }
- printf("\n");
- }
- }
-
- out:
- if (hdl) {
- bitbang_close(hdl);
- }
- gpio_close(&ctx.sc_clk);
- gpio_close(&ctx.sc_miso);
- gpio_close(&ctx.sc_mosi);
- if (cs != -1) {
- /* reset have chip select */
- gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
- ? GPIO_VALUE_LOW : GPIO_VALUE_HIGH));
- gpio_close(&cs_gpio);
- }
-
- if (read_buf) {
- free(read_buf);
- }
- if (write_buf) {
- free(write_buf);
- }
- return rc;
-}
OpenPOWER on IntegriCloud