diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.14/950-0138-Updates-for-Pisound-module-code.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.14/950-0138-Updates-for-Pisound-module-code.patch | 422 |
1 files changed, 0 insertions, 422 deletions
diff --git a/target/linux/brcm2708/patches-4.14/950-0138-Updates-for-Pisound-module-code.patch b/target/linux/brcm2708/patches-4.14/950-0138-Updates-for-Pisound-module-code.patch deleted file mode 100644 index af501d56f4..0000000000 --- a/target/linux/brcm2708/patches-4.14/950-0138-Updates-for-Pisound-module-code.patch +++ /dev/null @@ -1,422 +0,0 @@ -From 5f3557a2e88b324e026d44f8fb7eb3ea37bba16b Mon Sep 17 00:00:00 2001 -From: Giedrius Trainavicius <giedrius@blokas.io> -Date: Tue, 25 Oct 2016 01:47:20 +0300 -Subject: [PATCH 138/454] Updates for Pisound module code: - - * Merged 'Fix a warning in DEBUG builds' (1c8b82b). - * Updating some strings and copyright information. - * Fix for handling high load of MIDI input and output. - * Use dual rate oversampling ratio for 96kHz instead of single - rate one. - -Signed-off-by: Giedrius Trainavicius <giedrius@blokas.io> ---- - .../arm/boot/dts/overlays/pisound-overlay.dts | 4 +- - sound/soc/bcm/pisound.c | 209 ++++++++++++------ - 2 files changed, 146 insertions(+), 67 deletions(-) - ---- a/arch/arm/boot/dts/overlays/pisound-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pisound-overlay.dts -@@ -1,6 +1,6 @@ - /* -- * pisound Linux kernel module. -- * Copyright (C) 2016 Vilniaus Blokas UAB, http://blokas.io/pisound -+ * Pisound Linux kernel module. -+ * Copyright (C) 2016-2017 Vilniaus Blokas UAB, https://blokas.io/pisound - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License ---- a/sound/soc/bcm/pisound.c -+++ b/sound/soc/bcm/pisound.c -@@ -1,6 +1,6 @@ - /* -- * pisound Linux kernel module. -- * Copyright (C) 2016 Vilniaus Blokas UAB, http://blokas.io/pisound -+ * Pisound Linux kernel module. -+ * Copyright (C) 2016-2017 Vilniaus Blokas UAB, https://blokas.io/pisound - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -28,6 +28,7 @@ - #include <linux/spi/spi.h> - #include <linux/interrupt.h> - #include <linux/kfifo.h> -+#include <linux/jiffies.h> - - #include <sound/core.h> - #include <sound/pcm.h> -@@ -41,7 +42,8 @@ - static int pisnd_spi_init(struct device *dev); - static void pisnd_spi_uninit(void); - --static void pisnd_spi_send(uint8_t val); -+static void pisnd_spi_flush(void); -+static void pisnd_spi_start(void); - static uint8_t pisnd_spi_recv(uint8_t *buffer, uint8_t length); - - typedef void (*pisnd_spi_recv_cb)(void *data); -@@ -56,7 +58,7 @@ static void pisnd_midi_uninit(void); - - #define PISOUND_LOG_PREFIX "pisound: " - --#ifdef DEBUG -+#ifdef PISOUND_DEBUG - # define printd(...) pr_alert(PISOUND_LOG_PREFIX __VA_ARGS__) - #else - # define printd(...) do {} while (0) -@@ -65,13 +67,18 @@ static void pisnd_midi_uninit(void); - #define printe(...) pr_err(PISOUND_LOG_PREFIX __VA_ARGS__) - #define printi(...) pr_info(PISOUND_LOG_PREFIX __VA_ARGS__) - -+static struct snd_rawmidi *g_rmidi; -+static struct snd_rawmidi_substream *g_midi_output_substream; -+ - static int pisnd_output_open(struct snd_rawmidi_substream *substream) - { -+ g_midi_output_substream = substream; - return 0; - } - - static int pisnd_output_close(struct snd_rawmidi_substream *substream) - { -+ g_midi_output_substream = NULL; - return 0; - } - -@@ -80,26 +87,20 @@ static void pisnd_output_trigger( - int up - ) - { -- uint8_t data; -+ if (substream != g_midi_output_substream) { -+ printe("MIDI output trigger called for an unexpected stream!"); -+ return; -+ } - - if (!up) - return; - -- while (snd_rawmidi_transmit_peek(substream, &data, 1)) { -- pisnd_spi_send(data); -- snd_rawmidi_transmit_ack(substream, 1); -- } -+ pisnd_spi_start(); - } - - static void pisnd_output_drain(struct snd_rawmidi_substream *substream) - { -- uint8_t data; -- -- while (snd_rawmidi_transmit_peek(substream, &data, 1)) { -- pisnd_spi_send(data); -- -- snd_rawmidi_transmit_ack(substream, 1); -- } -+ pisnd_spi_flush(); - } - - static int pisnd_input_open(struct snd_rawmidi_substream *substream) -@@ -120,7 +121,7 @@ static void pisnd_midi_recv_callback(voi - while ((n = pisnd_spi_recv(data, sizeof(data)))) { - int res = snd_rawmidi_receive(substream, data, n); - (void)res; -- printd("midi recv 0x%02x, res = %d\n", data, res); -+ printd("midi recv %u bytes, res = %d\n", n, res); - } - } - -@@ -134,8 +135,6 @@ static void pisnd_input_trigger(struct s - } - } - --static struct snd_rawmidi *g_rmidi; -- - static struct snd_rawmidi_ops pisnd_output_ops = { - .open = pisnd_output_open, - .close = pisnd_output_close, -@@ -168,7 +167,11 @@ static struct snd_rawmidi_global_ops pis - - static int pisnd_midi_init(struct snd_card *card) - { -- int err = snd_rawmidi_new(card, "pisound MIDI", 0, 1, 1, &g_rmidi); -+ int err; -+ -+ g_midi_output_substream = NULL; -+ -+ err = snd_rawmidi_new(card, "pisound MIDI", 0, 1, 1, &g_rmidi); - - if (err < 0) { - printe("snd_rawmidi_new failed: %d\n", err); -@@ -209,7 +212,7 @@ static void pisnd_midi_uninit(void) - static void *g_recvData; - static pisnd_spi_recv_cb g_recvCallback; - --#define FIFO_SIZE 512 -+#define FIFO_SIZE 4096 - - static char g_serial_num[11]; - static char g_id[25]; -@@ -231,6 +234,7 @@ static struct work_struct pisnd_work_pro - - static void pisnd_work_handler(struct work_struct *work); - -+static void spi_transfer(const uint8_t *txbuf, uint8_t *rxbuf, int len); - static uint16_t spi_transfer16(uint16_t val); - - static int pisnd_init_workqueues(void) -@@ -285,9 +289,6 @@ static unsigned long spilockflags; - - static uint16_t spi_transfer16(uint16_t val) - { -- int err; -- struct spi_transfer transfer; -- struct spi_message msg; - uint8_t txbuf[2]; - uint8_t rxbuf[2]; - -@@ -296,19 +297,38 @@ static uint16_t spi_transfer16(uint16_t - return 0; - } - -+ txbuf[0] = val >> 8; -+ txbuf[1] = val & 0xff; -+ -+ spi_transfer(txbuf, rxbuf, sizeof(txbuf)); -+ -+ printd("received: %02x%02x\n", rxbuf[0], rxbuf[1]); -+ -+ return (rxbuf[0] << 8) | rxbuf[1]; -+} -+ -+static void spi_transfer(const uint8_t *txbuf, uint8_t *rxbuf, int len) -+{ -+ int err; -+ struct spi_transfer transfer; -+ struct spi_message msg; -+ -+ memset(rxbuf, 0, sizeof(txbuf)); -+ -+ if (!pisnd_spi_device) { -+ printe("pisnd_spi_device null, returning\n"); -+ return; -+ } -+ - spi_message_init(&msg); - - memset(&transfer, 0, sizeof(transfer)); -- memset(&rxbuf, 0, sizeof(rxbuf)); - -- txbuf[0] = val >> 8; -- txbuf[1] = val & 0xff; -- -- transfer.tx_buf = &txbuf; -- transfer.rx_buf = &rxbuf; -- transfer.len = sizeof(txbuf); -- transfer.speed_hz = 125000; -- transfer.delay_usecs = 100; -+ transfer.tx_buf = txbuf; -+ transfer.rx_buf = rxbuf; -+ transfer.len = len; -+ transfer.speed_hz = 100000; -+ transfer.delay_usecs = 10; - spi_message_add_tail(&transfer, &msg); - - spin_lock_irqsave(&spilock, spilockflags); -@@ -317,13 +337,10 @@ static uint16_t spi_transfer16(uint16_t - - if (err < 0) { - printe("spi_sync error %d\n", err); -- return 0; -+ return; - } - -- printd("received: %02x%02x\n", rxbuf[0], rxbuf[1]); - printd("hasMore %d\n", pisnd_spi_has_more()); -- -- return (rxbuf[0] << 8) | rxbuf[1]; - } - - static int spi_read_bytes(char *dst, size_t length, uint8_t *bytesRead) -@@ -335,7 +352,7 @@ static int spi_read_bytes(char *dst, siz - memset(dst, 0, length); - *bytesRead = 0; - -- rx = spi_transfer16(0); -+ rx = spi_transfer16(0); - if (!(rx >> 8)) - return -EINVAL; - -@@ -388,35 +405,90 @@ static struct spi_device *pisnd_spi_find - - static void pisnd_work_handler(struct work_struct *work) - { -- uint16_t rx; -- uint16_t tx; -+ enum { TRANSFER_SIZE = 4 }; -+ enum { PISOUND_OUTPUT_BUFFER_SIZE = 128 }; -+ enum { MIDI_BYTES_PER_SECOND = 3125 }; -+ int out_buffer_used = 0; -+ unsigned long now; - uint8_t val; -+ uint8_t txbuf[TRANSFER_SIZE]; -+ uint8_t rxbuf[TRANSFER_SIZE]; -+ uint8_t midibuf[TRANSFER_SIZE]; -+ int i, n; -+ bool had_data; -+ -+ unsigned long last_transfer_at = jiffies; - - if (work == &pisnd_work_process) { - if (pisnd_spi_device == NULL) - return; - - do { -- val = 0; -- tx = 0; -+ if (g_midi_output_substream && -+ kfifo_avail(&spi_fifo_out) >= sizeof(midibuf)) { - -- if (g_ledFlashDurationChanged) { -- tx = 0xf000 | g_ledFlashDuration; -- g_ledFlashDuration = 0; -- g_ledFlashDurationChanged = false; -- } else if (kfifo_get(&spi_fifo_out, &val)) { -- tx = 0x0f00 | val; -+ n = snd_rawmidi_transmit_peek( -+ g_midi_output_substream, -+ midibuf, sizeof(midibuf) -+ ); -+ -+ if (n > 0) { -+ for (i = 0; i < n; ++i) -+ kfifo_put( -+ &spi_fifo_out, -+ midibuf[i] -+ ); -+ snd_rawmidi_transmit_ack( -+ g_midi_output_substream, -+ i -+ ); -+ } - } - -- rx = spi_transfer16(tx); -+ had_data = false; -+ memset(txbuf, 0, sizeof(txbuf)); -+ for (i = 0; i < sizeof(txbuf) && -+ out_buffer_used < PISOUND_OUTPUT_BUFFER_SIZE; -+ i += 2) { -+ -+ val = 0; -+ -+ if (g_ledFlashDurationChanged) { -+ txbuf[i+0] = 0xf0; -+ txbuf[i+1] = g_ledFlashDuration; -+ g_ledFlashDuration = 0; -+ g_ledFlashDurationChanged = false; -+ } else if (kfifo_get(&spi_fifo_out, &val)) { -+ txbuf[i+0] = 0x0f; -+ txbuf[i+1] = val; -+ ++out_buffer_used; -+ } -+ } - -- if (rx & 0xff00) { -- kfifo_put(&spi_fifo_in, rx & 0xff); -- if (kfifo_len(&spi_fifo_in) > 16 -- && g_recvCallback) -- g_recvCallback(g_recvData); -+ spi_transfer(txbuf, rxbuf, sizeof(txbuf)); -+ /* Estimate the Pisound's MIDI output buffer usage, so -+ * that we don't overflow it. Space in the buffer should -+ * be becoming available at the UART MIDI byte transfer -+ * rate. -+ */ -+ now = jiffies; -+ out_buffer_used -= -+ (MIDI_BYTES_PER_SECOND / HZ) / -+ (now - last_transfer_at); -+ if (out_buffer_used < 0) -+ out_buffer_used = 0; -+ last_transfer_at = now; -+ -+ for (i = 0; i < sizeof(rxbuf); i += 2) { -+ if (rxbuf[i]) { -+ kfifo_put(&spi_fifo_in, rxbuf[i+1]); -+ if (kfifo_len(&spi_fifo_in) > 16 && -+ g_recvCallback) -+ g_recvCallback(g_recvData); -+ had_data = true; -+ } - } -- } while (rx != 0 -+ } while (had_data - || !kfifo_is_empty(&spi_fifo_out) - || pisnd_spi_has_more() - || g_ledFlashDurationChanged -@@ -492,7 +564,7 @@ static int spi_read_info(void) - if (!(tmp >> 8)) - return -EINVAL; - -- count = tmp & 0xff; -+ count = tmp & 0xff; - - for (i = 0; i < count; ++i) { - memset(buffer, 0, sizeof(buffer)); -@@ -628,10 +700,17 @@ static void pisnd_spi_flash_leds(uint8_t - pisnd_schedule_process(TASK_PROCESS); - } - --static void pisnd_spi_send(uint8_t val) -+static void pisnd_spi_flush(void) -+{ -+ while (!kfifo_is_empty(&spi_fifo_out)) { -+ pisnd_spi_start(); -+ flush_workqueue(pisnd_workqueue); -+ } -+} -+ -+static void pisnd_spi_start(void) - { -- kfifo_put(&spi_fifo_out, val); -- printd("schedule from spi_send\n"); -+ printd("schedule from spi_start\n"); - pisnd_schedule_process(TASK_PROCESS); - } - -@@ -765,7 +844,7 @@ static int pisnd_hw_params( - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - -- /* pisound runs on fixed 32 clock counts per channel, -+ /* Pisound runs on fixed 32 clock counts per channel, - * as generated by the master ADC. - */ - snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2); -@@ -786,8 +865,8 @@ static int pisnd_hw_params( - break; - case 96000: - gpiod_set_value(osr0, true); -- gpiod_set_value(osr1, true); -- gpiod_set_value(osr2, false); -+ gpiod_set_value(osr1, false); -+ gpiod_set_value(osr2, true); - break; - case 192000: - gpiod_set_value(osr0, true); -@@ -1030,7 +1109,7 @@ static int pisnd_probe(struct platform_d - return ret; - } - -- printi("Detected pisound card:\n"); -+ printi("Detected Pisound card:\n"); - printi("\tSerial: %s\n", pisnd_spi_get_serial()); - printi("\tVersion: %s\n", pisnd_spi_get_version()); - printi("\tId: %s\n", pisnd_spi_get_id()); -@@ -1119,5 +1198,5 @@ static struct platform_driver pisnd_driv - module_platform_driver(pisnd_driver); - - MODULE_AUTHOR("Giedrius Trainavicius <giedrius@blokas.io>"); --MODULE_DESCRIPTION("ASoC Driver for pisound, http://blokas.io/pisound"); -+MODULE_DESCRIPTION("ASoC Driver for Pisound, https://blokas.io/pisound"); - MODULE_LICENSE("GPL v2"); |