Last active
October 13, 2015 08:33
-
-
Save pelwell/4df57791157259758cf6 to your computer and use it in GitHub Desktop.
This diff is the result of replacing the downstream I2S driver with the @HiassofT's modified upstream I2S driver after a simple 2835->2708 textual substitution, because I find it makes it easier to understand the consequences of switching. As you can see, the two drivers are virtually identical.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c | |
index ad9ca2c..1eeb131 100644 | |
--- a/sound/soc/bcm/bcm2708-i2s.c | |
+++ b/sound/soc/bcm/bcm2708-i2s.c | |
@@ -31,8 +31,6 @@ | |
* General Public License for more details. | |
*/ | |
-#include "bcm2708-i2s.h" | |
- | |
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/device.h> | |
@@ -40,9 +38,7 @@ | |
#include <linux/delay.h> | |
#include <linux/io.h> | |
#include <linux/clk.h> | |
-#ifndef CONFIG_ARCH_BCM2835 | |
-#include <mach/gpio.h> | |
-#endif | |
+#include <linux/of_address.h> | |
#include <sound/core.h> | |
#include <sound/pcm.h> | |
@@ -51,8 +47,6 @@ | |
#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 | |
@@ -165,14 +159,6 @@ static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = { | |
#define BCM2708_I2S_INT_RXR BIT(1) | |
#define BCM2708_I2S_INT_TXW BIT(0) | |
-/* I2S DMA interface */ | |
-#define BCM2708_I2S_FIFO_PHYSICAL_ADDR 0x7E203004 | |
-#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; | |
@@ -184,12 +170,6 @@ 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 */ | |
@@ -321,71 +301,6 @@ static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, | |
return 0; | |
} | |
- | |
-#ifdef CONFIG_ARCH_BCM2835 | |
-static void bcm2708_i2s_setup_gpio(void) { } | |
-#else | |
-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) | |
-{ | |
- /* | |
- * This is the common way to handle the GPIO pins for | |
- * the Raspberry Pi. | |
- * TODO Better way would be to handle | |
- * this in the device tree! | |
- */ | |
- 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; | |
- } | |
- | |
- 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; | |
- } | |
- | |
- /* configure I2S pins to correct ALT mode */ | |
- for (pin = startpin; pin <= startpin+3; pin++) { | |
- bcm2708_i2s_set_function(pin, alt); | |
- } | |
-} | |
-#endif | |
- | |
static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, | |
struct snd_pcm_hw_params *params, | |
struct snd_soc_dai *dai) | |
@@ -415,9 +330,6 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, | |
if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) | |
return 0; | |
- if (!dev->dev->of_node) | |
- bcm2708_i2s_setup_gpio(); | |
- | |
/* | |
* Adjust the data length according to the format. | |
* We prefill the half frame length with an integer | |
@@ -792,8 +704,9 @@ static int bcm2708_i2s_dai_probe(struct snd_soc_dai *dai) | |
{ | |
struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
- dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; | |
- dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; | |
+ snd_soc_dai_init_dma_data(dai, | |
+ &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK], | |
+ &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]); | |
return 0; | |
} | |
@@ -899,7 +812,6 @@ static const struct snd_dmaengine_pcm_config bcm2708_dmaengine_pcm_config = { | |
.prealloc_buffer_size = 256 * PAGE_SIZE, | |
}; | |
- | |
static int bcm2708_i2s_probe(struct platform_device *pdev) | |
{ | |
struct bcm2708_i2s_dev *dev; | |
@@ -907,6 +819,15 @@ static int bcm2708_i2s_probe(struct platform_device *pdev) | |
int ret; | |
struct regmap *regmap[2]; | |
struct resource *mem[2]; | |
+ const __be32 *addr; | |
+ dma_addr_t dma_reg_base; | |
+ | |
+ addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); | |
+ if (!addr) { | |
+ dev_err(&pdev->dev, "could not get DMA-register address\n"); | |
+ return -ENODEV; | |
+ } | |
+ dma_reg_base = be32_to_cpup(addr); | |
if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) | |
bcm2708_pcm_hardware.info |= | |
@@ -924,32 +845,24 @@ static int bcm2708_i2s_probe(struct platform_device *pdev) | |
regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, | |
&bcm2708_regmap_config[i]); | |
- if (IS_ERR(regmap[i])) { | |
- dev_err(&pdev->dev, "I2S probe: regmap init failed\n"); | |
+ if (IS_ERR(regmap[i])) | |
return PTR_ERR(regmap[i]); | |
- } | |
} | |
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), | |
GFP_KERNEL); | |
- if (IS_ERR(dev)) | |
- return PTR_ERR(dev); | |
+ if (!dev) | |
+ return -ENOMEM; | |
dev->i2s_regmap = regmap[0]; | |
dev->clk_regmap = regmap[1]; | |
/* Set the DMA address */ | |
dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = | |
- (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; | |
+ dma_reg_base + BCM2708_I2S_FIFO_A_REG; | |
dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = | |
- (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; | |
- | |
- /* Set the DREQ */ | |
- dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].slave_id = | |
- BCM2708_DMA_DREQ_PCM_TX; | |
- dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].slave_id = | |
- BCM2708_DMA_DREQ_PCM_RX; | |
+ dma_reg_base + BCM2708_I2S_FIFO_A_REG; | |
/* Set the bus width */ | |
dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = | |
@@ -968,34 +881,24 @@ static int bcm2708_i2s_probe(struct platform_device *pdev) | |
dev->dev = &pdev->dev; | |
dev_set_drvdata(&pdev->dev, dev); | |
- ret = snd_soc_register_component(&pdev->dev, | |
+ ret = devm_snd_soc_register_component(&pdev->dev, | |
&bcm2708_i2s_component, &bcm2708_i2s_dai, 1); | |
- | |
if (ret) { | |
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | |
- ret = -ENOMEM; | |
return ret; | |
} | |
- ret = snd_dmaengine_pcm_register(&pdev->dev, | |
- &bcm2708_dmaengine_pcm_config, | |
- SND_DMAENGINE_PCM_FLAG_COMPAT); | |
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, | |
+ &bcm2708_dmaengine_pcm_config, | |
+ SND_DMAENGINE_PCM_FLAG_COMPAT); | |
if (ret) { | |
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | |
- snd_soc_unregister_component(&pdev->dev); | |
return ret; | |
} | |
return 0; | |
} | |
-static int bcm2708_i2s_remove(struct platform_device *pdev) | |
-{ | |
- snd_dmaengine_pcm_unregister(&pdev->dev); | |
- snd_soc_unregister_component(&pdev->dev); | |
- return 0; | |
-} | |
- | |
static const struct of_device_id bcm2708_i2s_of_match[] = { | |
{ .compatible = "brcm,bcm2708-i2s", }, | |
{}, | |
@@ -1004,10 +907,8 @@ MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); | |
static struct platform_driver bcm2708_i2s_driver = { | |
.probe = bcm2708_i2s_probe, | |
- .remove = bcm2708_i2s_remove, | |
.driver = { | |
.name = "bcm2708-i2s", | |
- .owner = THIS_MODULE, | |
.of_match_table = bcm2708_i2s_of_match, | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment