meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/0001-ASoC-Add-BCM2708-fixes.patch
Petter Mabäcker e1c5efc658 linux-raspberrypi: Add 3.14 support
Add basic support for Linux 3.14, cherry-pick changes from 3.18.y in
order to solve some debugfs warnings and get better support
for i2s for BCM2708.

- 3.14 lacks BCM2709 support and will not by default be able to use for
raspberry pi 2.

Below warnings still exists they are harmless and exists due to that
snd_soc_pcm512x is triggered to be loaded twice. The problem is solved
after device tree support for the driver was introduced in 3.18.y and no
easy solution exists to solve this problem on older kernel versions (see
https://github.com/raspberrypi/linux/issues/662 for more info).

   pcm512x 1-004c: Failed to reset device: -5
   pcm512x: probe of 1-004c failed with error

Remove sl030raspberrypii2ckernel.patch since it will not apply anymore
and its content seems to be obsolite after cherry-picking
'558d0bf Fix grabbing lock from atomic context in i2c driver'.

[Support #57]

Signed-off-by: Petter Mabäcker <petter@technux.se>
Signed-off-by: Andrei Gherzan <andrei@gherzan.ro>
2015-05-18 00:48:49 +02:00

264 lines
7.6 KiB
Diff

From e73a69601c65103b0e032e6093af0f00a1e1af3a Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:33:38 +0100
Subject: [PATCH 1/2] ASoC: Add BCM2708 fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry-pick remaining parts of
730cb8a1216f9da3d097072cd9bb06e0db348172)
bcm2708-i2s: Update bclk_ratio to more correct values
Move GPIO setup to hw_params.
This is used to stop the I2S driver from breaking
the GPIO setup for other uses of the PCM interface
Configure GPIOs for I2S based on revision/card settings
With RPi model B+, assignment of the I2S GPIO pins has changed.
This patch uses the board revision to auto-detect the GPIOs used
for I2S. It also allows sound card drivers to set the GPIOs that
should be used. This is especially important with the Compute
Module.
bcm2708-i2s: Avoid leak from iomap when accessing gpio
bcm2708: Eliminate i2s debugfs directory error
Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk')
to avoid the name clash when registering debugfs entries.
Upstream-Status: Pending
Signed-off-by: Petter Mabäcker <petter@technux.se>
Conflicts:
sound/soc/bcm/Kconfig
sound/soc/bcm/Makefile
sound/soc/bcm/bcm2708-i2s.c
---
sound/soc/bcm/bcm2708-i2s.c | 82 ++++++++++++++++++++++++++++++++++++---------
sound/soc/bcm/bcm2708-i2s.h | 35 +++++++++++++++++++
2 files changed, 102 insertions(+), 15 deletions(-)
create mode 100644 sound/soc/bcm/bcm2708-i2s.h
diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c
index 9976571..3fcb740 100644
--- a/sound/soc/bcm/bcm2708-i2s.c
+++ b/sound/soc/bcm/bcm2708-i2s.c
@@ -31,6 +31,8 @@
* General Public License for more details.
*/
+#include "bcm2708-i2s.h"
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
@@ -38,6 +40,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <mach/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -46,6 +49,8 @@
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
+#include <asm/system_info.h>
+
/* Clock registers */
#define BCM2708_CLK_PCMCTL_REG 0x00
#define BCM2708_CLK_PCMDIV_REG 0x04
@@ -163,6 +168,9 @@ static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = {
#define BCM2708_DMA_DREQ_PCM_TX 2
#define BCM2708_DMA_DREQ_PCM_RX 3
+/* I2S pin configuration */
+static int bcm2708_i2s_gpio=BCM2708_I2S_GPIO_AUTO;
+
/* General device struct */
struct bcm2708_i2s_dev {
struct device *dev;
@@ -174,6 +182,12 @@ struct bcm2708_i2s_dev {
struct regmap *clk_regmap;
};
+void bcm2708_i2s_set_gpio(int gpio) {
+ bcm2708_i2s_gpio=gpio;
+}
+EXPORT_SYMBOL(bcm2708_i2s_set_gpio);
+
+
static void bcm2708_i2s_start_clock(struct bcm2708_i2s_dev *dev)
{
/* Start the clock if in master mode */
@@ -306,6 +320,25 @@ static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
}
+static int bcm2708_i2s_set_function(unsigned offset, int function)
+{
+ #define GPIOFSEL(x) (0x00+(x)*4)
+ void __iomem *gpio = __io_address(GPIO_BASE);
+ unsigned alt = function <= 3 ? function + 4: function == 4 ? 3 : 2;
+ unsigned gpiodir;
+ unsigned gpio_bank = offset / 10;
+ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3;
+
+ if (offset >= BCM2708_NR_GPIOS)
+ return -EINVAL;
+
+ gpiodir = readl(gpio + GPIOFSEL(gpio_bank));
+ gpiodir &= ~(7 << gpio_field_offset);
+ gpiodir |= alt << gpio_field_offset;
+ writel(gpiodir, gpio + GPIOFSEL(gpio_bank));
+ return 0;
+}
+
static void bcm2708_i2s_setup_gpio(void)
{
/*
@@ -314,20 +347,37 @@ static void bcm2708_i2s_setup_gpio(void)
* TODO Better way would be to handle
* this in the device tree!
*/
-#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
-#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
+ int pin,pinconfig,startpin,alt;
+
+ /* SPI is on different GPIOs on different boards */
+ /* for Raspberry Pi B+, this is pin GPIO18-21, for original on 28-31 */
+ if (bcm2708_i2s_gpio==BCM2708_I2S_GPIO_AUTO) {
+ if ((system_rev & 0xffffff) >= 0x10) {
+ /* Model B+ */
+ pinconfig=BCM2708_I2S_GPIO_PIN18;
+ } else {
+ /* original */
+ pinconfig=BCM2708_I2S_GPIO_PIN28;
+ }
+ } else {
+ pinconfig=bcm2708_i2s_gpio;
+ }
- unsigned int *gpio;
- int pin;
- gpio = ioremap(GPIO_BASE, SZ_16K);
+ if (pinconfig==BCM2708_I2S_GPIO_PIN18) {
+ startpin=18;
+ alt=BCM2708_I2S_GPIO_PIN18_ALT;
+ } else if (pinconfig==BCM2708_I2S_GPIO_PIN28) {
+ startpin=28;
+ alt=BCM2708_I2S_GPIO_PIN28_ALT;
+ } else {
+ printk(KERN_INFO "Can't configure I2S GPIOs, unknown pin mode for I2S: %i\n",pinconfig);
+ return;
+ }
- /* SPI is on GPIO 7..11 */
- for (pin = 28; pin <= 31; pin++) {
- INP_GPIO(pin); /* set mode to GPIO input first */
- SET_GPIO_ALT(pin, 2); /* set mode to ALT 0 */
+ /* configure I2S pins to correct ALT mode */
+ for (pin = startpin; pin <= startpin+3; pin++) {
+ bcm2708_i2s_set_function(pin, alt);
}
-#undef INP_GPIO
-#undef SET_GPIO_ALT
}
static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream,
@@ -372,15 +422,15 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
data_length = 16;
- bclk_ratio = 40;
+ bclk_ratio = 50;
break;
case SNDRV_PCM_FORMAT_S24_LE:
data_length = 24;
- bclk_ratio = 40;
+ bclk_ratio = 50;
break;
case SNDRV_PCM_FORMAT_S32_LE:
data_length = 32;
- bclk_ratio = 80;
+ bclk_ratio = 100;
break;
default:
return -EINVAL;
@@ -746,7 +796,7 @@ static struct snd_soc_dai_driver bcm2708_i2s_dai = {
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE
- // | SNDRV_PCM_FMTBIT_S24_LE : disable for now, it causes white noise with xbmc
+ | SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S32_LE
},
.capture = {
@@ -803,6 +853,7 @@ static const struct regmap_config bcm2708_regmap_config[] = {
.precious_reg = bcm2708_i2s_precious_reg,
.volatile_reg = bcm2708_i2s_volatile_reg,
.cache_type = REGCACHE_RBTREE,
+ .name = "i2s",
},
{
.reg_bits = 32,
@@ -811,6 +862,7 @@ static const struct regmap_config bcm2708_regmap_config[] = {
.max_register = BCM2708_CLK_PCMDIV_REG,
.volatile_reg = bcm2708_clk_volatile_reg,
.cache_type = REGCACHE_RBTREE,
+ .name = "clk",
},
};
diff --git a/sound/soc/bcm/bcm2708-i2s.h b/sound/soc/bcm/bcm2708-i2s.h
new file mode 100644
index 0000000..94fed6a
--- /dev/null
+++ b/sound/soc/bcm/bcm2708-i2s.h
@@ -0,0 +1,35 @@
+/*
+ * I2S configuration for sound cards.
+ *
+ * Copyright (c) 2014 Daniel Matuschek <daniel@hifiberry.com>
+ *
+ * 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
+ */
+
+#ifndef BCM2708_I2S_H
+#define BCM2708_I2S_H
+
+/* I2S pin assignment */
+#define BCM2708_I2S_GPIO_AUTO 0
+#define BCM2708_I2S_GPIO_PIN18 1
+#define BCM2708_I2S_GPIO_PIN28 2
+
+/* Alt mode to enable I2S */
+#define BCM2708_I2S_GPIO_PIN18_ALT 0
+#define BCM2708_I2S_GPIO_PIN28_ALT 2
+
+extern void bcm2708_i2s_set_gpio(int gpio);
+
+#endif
--
1.9.1