brcm2708: update to v3.18

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

SVN-Revision: 44392
This commit is contained in:
John Crispin 2015-02-11 10:17:55 +00:00
parent f90d9d486a
commit 408c969626
118 changed files with 312222 additions and 17 deletions

View file

@ -1,5 +1,5 @@
#
# Copyright (C) 2012-2014 OpenWrt.org
# Copyright (C) 2012-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@ -7,16 +7,15 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=brcm2708-gpu-fw
PKG_REV:=e25efc4545d0cef7c49c82e770b3e4ccfc8aba4c
PKG_VERSION:=20140226
PKG_RELEASE:=1
PKG_NAME:=brcm2708-gpu-fw-boot
PKG_VERSION:=2015-02-07
PKG_RELEASE:=$(PKG_SOURCE_VERSION)
PKG_MD5SUM:=f198d5466ec412424f3ca77703f29d15
PKG_SOURCE:=$(PKG_REV).tar.gz
PKG_SOURCE_URL:=https://github.com/Hexxeh/rpi-firmware/archive/
PKG_MD5SUM:=b1bb6b1063c4f920314274edd39c35e6
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_REV)
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
# PKG_SOURCE_SUBDIR:=$(PKG_NAME)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
@ -35,10 +34,5 @@ endef
define Build/Compile
endef
define Build/InstallDev
$(INSTALL_DIR) $(BUILD_DIR)/brcm2708-gpu-fw-boot
$(CP) $(PKG_BUILD_DIR)/* $(BUILD_DIR)/brcm2708-gpu-fw-boot
endef
$(eval $(call BuildPackage,brcm2708-gpu-fw))

View file

@ -1,5 +1,5 @@
#
# Copyright (C) 2012-2013 OpenWrt.org
# Copyright (C) 2012-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@ -15,7 +15,7 @@ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
CPU_TYPE:=arm1176jzf-s
CPU_SUBTYPE:=vfp
KERNEL_PATCHVER:=3.14
KERNEL_PATCHVER:=3.18
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += brcm2708-gpu-fw kmod-usb-hid kmod-sound-core kmod-sound-arm-bcm2835

269
target/linux/brcm2708/config-3.18 Executable file
View file

@ -0,0 +1,269 @@
# CONFIG_AIO is not set
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_AMBA_PL08X is not set
# CONFIG_APM_EMULATION is not set
CONFIG_ARCH_BCM2708=y
# CONFIG_ARCH_BCM2709 is not set
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
CONFIG_ARM=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_ERRATA_411920=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_NR_BANKS=8
# CONFIG_ARM_SP805_WATCHDOG is not set
CONFIG_ARM_THUMB=y
CONFIG_ARM_UNWIND=y
CONFIG_AVERAGE=y
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_BCM2708_DT is not set
CONFIG_BCM2708_GPIO=y
# CONFIG_BCM2708_NOL2CACHE is not set
CONFIG_BCM2708_VCHIQ=y
CONFIG_BCM2708_VCMEM=y
CONFIG_BCM2708_WDT=y
CONFIG_BCM_VC_CMA=y
CONFIG_BCM_VC_SM=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_SD=y
CONFIG_BRCM_CHAR_DRIVERS=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CMA=y
CONFIG_CMA_ALIGNMENT=8
CONFIG_CMA_AREAS=7
CONFIG_CMA_DEBUG=y
CONFIG_CMA_SIZE_MBYTES=16
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_CPU_32v6=y
CONFIG_CPU_ABRT_EV6=y
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V6=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_HAS_ASID=y
CONFIG_CPU_HAS_PMU=y
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_PABRT_V6=y
CONFIG_CPU_PM=y
CONFIG_CPU_TLB_V6=y
CONFIG_CPU_USE_DOMAINS=y
CONFIG_CPU_V6=y
CONFIG_CRC16=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_USER is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_DEVTMPFS=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2708=y
CONFIG_DMA_CMA=y
CONFIG_DNOTIFY=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_DW_DMAC_CORE is not set
CONFIG_ELF_CORE=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_FB=y
CONFIG_FB_BCM2708=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_WMT_GE_ROPS is not set
CONFIG_FIRMWARE_IN_KERNEL=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x16=y
CONFIG_FONT_8x8=y
# CONFIG_FPE_FASTFPE is not set
# CONFIG_FPE_NWFPE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FREEZER=y
CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
CONFIG_GENERIC_ACL=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HAMRADIO is not set
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_AOUT=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SPARSE_IRQ=y
CONFIG_HW_CONSOLE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_INPUT=y
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_IOSCHED_CFQ=y
CONFIG_JBD2=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_KTIME_SCALAR=y
# CONFIG_LCD_AMS369FG06 is not set
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_LCD_L4F00242T03 is not set
# CONFIG_LCD_LD9040 is not set
# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_PLATFORM is not set
# CONFIG_LCD_S6E63M0 is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
# CONFIG_LEDS_TRIGGER_INPUT is not set
# CONFIG_LEDS_TRIGGER_TIMER is not set
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_MACH_BCM2708=y
CONFIG_MAC_PARTITION=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_MMC=y
CONFIG_MMC_BCM2835=y
CONFIG_MMC_BCM2835_DMA=y
CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
# CONFIG_MTD is not set
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_MACH_MEMORY_H=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NLS=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NO_HZ=y
CONFIG_OABI_COMPAT=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PCI_SYSCALL is not set
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYS_OFFSET=0
# CONFIG_PL330_DMA is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
CONFIG_POWER_SUPPLY=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_PRINTK_TIME=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_RAW_DRIVER=y
# CONFIG_RTL8192CU is not set
CONFIG_SCSI=y
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_PROC_FS is not set
# CONFIG_SERIAL_8250 is not set
# CONFIG_SERIAL_AMBA_PL010 is not set
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
# CONFIG_SND_BCM2708_SOC_I2S is not set
# CONFIG_SQUASHFS is not set
# CONFIG_STAGING is not set
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_TEXTSEARCH is not set
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UEVENT_HELPER_PATH=""
# CONFIG_UID16 is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_XHCI is not set
CONFIG_USB_COMMON=y
# CONFIG_USB_DEVICEFS is not set
CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_DWCOTG=y
CONFIG_USB_LIBUSUAL=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_STORAGE=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_UAS=y
CONFIG_USB_USBNET=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VFP=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZONE_DMA_FLAG=0

View file

@ -462,6 +462,12 @@
##
#gpu_mem_512=128
## gpu_mem_1024
## GPU memory allocation in MB for 1024MB board revision.
## This option overrides gpu_mem.
##
#gpu_mem_1024=128
################################################################################
## Boot Option Settings
################################################################################

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,609 @@
From 4f339b429583965a8eb7c23474414d0730db1215 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 Oct 2014 18:50:05 +0100
Subject: [PATCH 002/114] Add bcm2708_gpio driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
bcm2708: Add extension to configure internal pulls
The bcm2708 gpio controller supports internal pulls to be used as pull-up,
pull-down or being entirely disabled. As it can be useful for a driver to
change the pull configuration from it's default pull-down state, add an
extension which allows configuring the pull per gpio.
Signed-off-by: Julian Scheel <julian@jusst.de>
bcm2708-gpio: Revert the use of pinctrl_request_gpio
In non-DT systems, pinctrl_request_gpio always fails causing
"requests probe deferral" messages. In DT systems, it isn't useful
because the reference counting is independent of the normal pinctrl
pin reservations.
gpio: Only clear the currently occurring interrupt. Avoids losing interrupts
See: linux #760
bcm2708_gpio: Avoid calling irq_unmask for all interrupts
When setting up the interrupts, specify that the handle_simple_irq
handler should be used. This leaves interrupt acknowledgement to
the caller, and prevents irq_unmask from being called for all
interrupts.
Issue: linux #760
---
arch/arm/mach-bcm2708/Kconfig | 8 +
arch/arm/mach-bcm2708/Makefile | 1 +
arch/arm/mach-bcm2708/bcm2708.c | 28 ++
arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++
arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++
include/linux/platform_data/bcm2708.h | 23 ++
6 files changed, 503 insertions(+)
create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c
create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h
create mode 100644 include/linux/platform_data/bcm2708.h
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
index 1f11478..9355841 100644
--- a/arch/arm/mach-bcm2708/Kconfig
+++ b/arch/arm/mach-bcm2708/Kconfig
@@ -9,6 +9,14 @@ config MACH_BCM2708
help
Include support for the Broadcom(R) BCM2708 platform.
+config BCM2708_GPIO
+ bool "BCM2708 gpio support"
+ depends on MACH_BCM2708
+ select ARCH_REQUIRE_GPIOLIB
+ default y
+ help
+ Include support for the Broadcom(R) BCM2708 gpio.
+
config BCM2708_VCMEM
bool "Videocore Memory"
depends on MACH_BCM2708
diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile
index c76f39bc..a722f3f 100644
--- a/arch/arm/mach-bcm2708/Makefile
+++ b/arch/arm/mach-bcm2708/Makefile
@@ -3,4 +3,5 @@
#
obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o
+obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o
obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 9b4e709..7503649 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -331,6 +331,31 @@ static struct platform_device bcm2708_vcio_device = {
},
};
+#ifdef CONFIG_BCM2708_GPIO
+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
+
+static struct resource bcm2708_gpio_resources[] = {
+ [0] = { /* general purpose I/O */
+ .start = GPIO_BASE,
+ .end = GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_gpio_device = {
+ .name = BCM_GPIO_DRIVER_NAME,
+ .id = -1, /* only one VideoCore I/O area */
+ .resource = bcm2708_gpio_resources,
+ .num_resources = ARRAY_SIZE(bcm2708_gpio_resources),
+ .dev = {
+ .dma_mask = &gpio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+ },
+};
+#endif
+
static struct resource bcm2708_systemtimer_resources[] = {
[0] = { /* system timer access */
.start = ST_BASE,
@@ -473,6 +498,9 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2708_dmaman_device);
bcm_register_device(&bcm2708_vcio_device);
+#ifdef CONFIG_BCM2708_GPIO
+ bcm_register_device(&bcm2708_gpio_device);
+#endif
bcm_register_device(&bcm2708_systemtimer_device);
bcm_register_device(&bcm2708_fb_device);
bcm_register_device(&bcm2708_usb_device);
diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c
new file mode 100644
index 0000000..c1e9254
--- /dev/null
+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c
@@ -0,0 +1,426 @@
+/*
+ * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
+ *
+ * Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <mach/gpio.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <mach/platform.h>
+#include <linux/pinctrl/consumer.h>
+
+#include <linux/platform_data/bcm2708.h>
+
+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
+#define DRIVER_NAME BCM_GPIO_DRIVER_NAME
+#define BCM_GPIO_USE_IRQ 1
+
+#define GPIOFSEL(x) (0x00+(x)*4)
+#define GPIOSET(x) (0x1c+(x)*4)
+#define GPIOCLR(x) (0x28+(x)*4)
+#define GPIOLEV(x) (0x34+(x)*4)
+#define GPIOEDS(x) (0x40+(x)*4)
+#define GPIOREN(x) (0x4c+(x)*4)
+#define GPIOFEN(x) (0x58+(x)*4)
+#define GPIOHEN(x) (0x64+(x)*4)
+#define GPIOLEN(x) (0x70+(x)*4)
+#define GPIOAREN(x) (0x7c+(x)*4)
+#define GPIOAFEN(x) (0x88+(x)*4)
+#define GPIOUD(x) (0x94+(x)*4)
+#define GPIOUDCLK(x) (0x98+(x)*4)
+
+#define GPIO_BANKS 2
+
+enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT,
+ GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4,
+ GPIO_FSEL_ALT0, GPIO_FSEL_ALT1,
+ GPIO_FSEL_ALT2, GPIO_FSEL_ALT3,
+};
+
+ /* Each of the two spinlocks protects a different set of hardware
+ * regiters and data structurs. This decouples the code of the IRQ from
+ * the GPIO code. This also makes the case of a GPIO routine call from
+ * the IRQ code simpler.
+ */
+static DEFINE_SPINLOCK(lock); /* GPIO registers */
+
+struct bcm2708_gpio {
+ struct list_head list;
+ void __iomem *base;
+ struct gpio_chip gc;
+ unsigned long rising[(BCM2708_NR_GPIOS + 31) / 32];
+ unsigned long falling[(BCM2708_NR_GPIOS + 31) / 32];
+ unsigned long high[(BCM2708_NR_GPIOS + 31) / 32];
+ unsigned long low[(BCM2708_NR_GPIOS + 31) / 32];
+};
+
+static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset,
+ int function)
+{
+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+ unsigned long flags;
+ unsigned gpiodir;
+ unsigned gpio_bank = offset / 10;
+ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3;
+
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function);
+ if (offset >= BCM2708_NR_GPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&lock, flags);
+
+ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
+ gpiodir &= ~(7 << gpio_field_offset);
+ gpiodir |= function << gpio_field_offset;
+ writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank));
+ spin_unlock_irqrestore(&lock, flags);
+ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
+
+ return 0;
+}
+
+static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset)
+{
+ return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT);
+}
+
+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
+static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset,
+ int value)
+{
+ int ret;
+ ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT);
+ if (ret >= 0)
+ bcm2708_gpio_set(gc, offset, value);
+ return ret;
+}
+
+static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+ unsigned gpio_bank = offset / 32;
+ unsigned gpio_field_offset = (offset - 32 * gpio_bank);
+ unsigned lev;
+
+ if (offset >= BCM2708_NR_GPIOS)
+ return 0;
+ lev = readl(gpio->base + GPIOLEV(gpio_bank));
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset));
+ return 0x1 & (lev >> gpio_field_offset);
+}
+
+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+ unsigned gpio_bank = offset / 32;
+ unsigned gpio_field_offset = (offset - 32 * gpio_bank);
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value);
+ if (offset >= BCM2708_NR_GPIOS)
+ return;
+ if (value)
+ writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
+ else
+ writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
+}
+
+/**********************
+ * extension to configure pullups
+ */
+int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
+ bcm2708_gpio_pull_t value)
+{
+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+ unsigned gpio_bank = offset / 32;
+ unsigned gpio_field_offset = (offset - 32 * gpio_bank);
+
+ if (offset >= BCM2708_NR_GPIOS)
+ return -EINVAL;
+
+ switch (value) {
+ case BCM2708_PULL_UP:
+ writel(2, gpio->base + GPIOUD(0));
+ break;
+ case BCM2708_PULL_DOWN:
+ writel(1, gpio->base + GPIOUD(0));
+ break;
+ case BCM2708_PULL_OFF:
+ writel(0, gpio->base + GPIOUD(0));
+ break;
+ }
+
+ udelay(5);
+ writel(1 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
+ udelay(5);
+ writel(0, gpio->base + GPIOUD(0));
+ writel(0 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
+
+ return 0;
+}
+EXPORT_SYMBOL(bcm2708_gpio_setpull);
+
+/*************************************************************************************************************************
+ * bcm2708 GPIO IRQ
+ */
+
+#if BCM_GPIO_USE_IRQ
+
+static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ return gpio_to_irq(gpio);
+}
+
+static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type)
+{
+ unsigned irq = d->irq;
+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
+ unsigned gn = irq_to_gpio(irq);
+ unsigned gb = gn / 32;
+ unsigned go = gn % 32;
+
+ gpio->rising[gb] &= ~(1 << go);
+ gpio->falling[gb] &= ~(1 << go);
+ gpio->high[gb] &= ~(1 << go);
+ gpio->low[gb] &= ~(1 << go);
+
+ if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ return -EINVAL;
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ gpio->rising[gb] |= (1 << go);
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ gpio->falling[gb] |= (1 << go);
+ if (type & IRQ_TYPE_LEVEL_HIGH)
+ gpio->high[gb] |= (1 << go);
+ if (type & IRQ_TYPE_LEVEL_LOW)
+ gpio->low[gb] |= (1 << go);
+ return 0;
+}
+
+static void bcm2708_gpio_irq_mask(struct irq_data *d)
+{
+ unsigned irq = d->irq;
+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
+ unsigned gn = irq_to_gpio(irq);
+ unsigned gb = gn / 32;
+ unsigned long rising = readl(gpio->base + GPIOREN(gb));
+ unsigned long falling = readl(gpio->base + GPIOFEN(gb));
+ unsigned long high = readl(gpio->base + GPIOHEN(gb));
+ unsigned long low = readl(gpio->base + GPIOLEN(gb));
+
+ gn = gn % 32;
+
+ writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
+ writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
+ writel(high & ~(1 << gn), gpio->base + GPIOHEN(gb));
+ writel(low & ~(1 << gn), gpio->base + GPIOLEN(gb));
+}
+
+static void bcm2708_gpio_irq_unmask(struct irq_data *d)
+{
+ unsigned irq = d->irq;
+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
+ unsigned gn = irq_to_gpio(irq);
+ unsigned gb = gn / 32;
+ unsigned go = gn % 32;
+ unsigned long rising = readl(gpio->base + GPIOREN(gb));
+ unsigned long falling = readl(gpio->base + GPIOFEN(gb));
+ unsigned long high = readl(gpio->base + GPIOHEN(gb));
+ unsigned long low = readl(gpio->base + GPIOLEN(gb));
+
+ if (gpio->rising[gb] & (1 << go)) {
+ writel(rising | (1 << go), gpio->base + GPIOREN(gb));
+ } else {
+ writel(rising & ~(1 << go), gpio->base + GPIOREN(gb));
+ }
+
+ if (gpio->falling[gb] & (1 << go)) {
+ writel(falling | (1 << go), gpio->base + GPIOFEN(gb));
+ } else {
+ writel(falling & ~(1 << go), gpio->base + GPIOFEN(gb));
+ }
+
+ if (gpio->high[gb] & (1 << go)) {
+ writel(high | (1 << go), gpio->base + GPIOHEN(gb));
+ } else {
+ writel(high & ~(1 << go), gpio->base + GPIOHEN(gb));
+ }
+
+ if (gpio->low[gb] & (1 << go)) {
+ writel(low | (1 << go), gpio->base + GPIOLEN(gb));
+ } else {
+ writel(low & ~(1 << go), gpio->base + GPIOLEN(gb));
+ }
+}
+
+static struct irq_chip bcm2708_irqchip = {
+ .name = "GPIO",
+ .irq_enable = bcm2708_gpio_irq_unmask,
+ .irq_disable = bcm2708_gpio_irq_mask,
+ .irq_unmask = bcm2708_gpio_irq_unmask,
+ .irq_mask = bcm2708_gpio_irq_mask,
+ .irq_set_type = bcm2708_gpio_irq_set_type,
+};
+
+static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id)
+{
+ unsigned long edsr;
+ unsigned bank;
+ int i;
+ unsigned gpio;
+ unsigned level_bits;
+ struct bcm2708_gpio *gpio_data = dev_id;
+
+ for (bank = 0; bank < GPIO_BANKS; bank++) {
+ edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank));
+ level_bits = gpio_data->high[bank] | gpio_data->low[bank];
+
+ for_each_set_bit(i, &edsr, 32) {
+ gpio = i + bank * 32;
+ /* ack edge triggered IRQs immediately */
+ if (!(level_bits & (1<<i)))
+ writel(1<<i,
+ __io_address(GPIO_BASE) + GPIOEDS(bank));
+ generic_handle_irq(gpio_to_irq(gpio));
+ /* ack level triggered IRQ after handling them */
+ if (level_bits & (1<<i))
+ writel(1<<i,
+ __io_address(GPIO_BASE) + GPIOEDS(bank));
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static struct irqaction bcm2708_gpio_irq = {
+ .name = "BCM2708 GPIO catchall handler",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = bcm2708_gpio_interrupt,
+};
+
+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
+{
+ unsigned irq;
+
+ ucb->gc.to_irq = bcm2708_gpio_to_irq;
+
+ for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) {
+ irq_set_chip_data(irq, ucb);
+ irq_set_chip_and_handler(irq, &bcm2708_irqchip,
+ handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ bcm2708_gpio_irq.dev_id = ucb;
+ setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq);
+}
+
+#else
+
+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
+{
+}
+
+#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */
+
+static int bcm2708_gpio_probe(struct platform_device *dev)
+{
+ struct bcm2708_gpio *ucb;
+ struct resource *res;
+ int bank;
+ int err = 0;
+
+ printk(KERN_INFO DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
+
+ ucb = kzalloc(sizeof(*ucb), GFP_KERNEL);
+ if (NULL == ucb) {
+ printk(KERN_ERR DRIVER_NAME ": failed to allocate "
+ "mailbox memory\n");
+ err = -ENOMEM;
+ goto err;
+ }
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+ platform_set_drvdata(dev, ucb);
+ ucb->base = __io_address(GPIO_BASE);
+
+ ucb->gc.label = "bcm2708_gpio";
+ ucb->gc.base = 0;
+ ucb->gc.ngpio = BCM2708_NR_GPIOS;
+ ucb->gc.owner = THIS_MODULE;
+
+ ucb->gc.direction_input = bcm2708_gpio_dir_in;
+ ucb->gc.direction_output = bcm2708_gpio_dir_out;
+ ucb->gc.get = bcm2708_gpio_get;
+ ucb->gc.set = bcm2708_gpio_set;
+ ucb->gc.can_sleep = 0;
+
+ for (bank = 0; bank < GPIO_BANKS; bank++) {
+ writel(0, ucb->base + GPIOREN(bank));
+ writel(0, ucb->base + GPIOFEN(bank));
+ writel(0, ucb->base + GPIOHEN(bank));
+ writel(0, ucb->base + GPIOLEN(bank));
+ writel(0, ucb->base + GPIOAREN(bank));
+ writel(0, ucb->base + GPIOAFEN(bank));
+ writel(~0, ucb->base + GPIOEDS(bank));
+ }
+
+ bcm2708_gpio_irq_init(ucb);
+
+ err = gpiochip_add(&ucb->gc);
+
+err:
+ return err;
+
+}
+
+static int bcm2708_gpio_remove(struct platform_device *dev)
+{
+ int err = 0;
+ struct bcm2708_gpio *ucb = platform_get_drvdata(dev);
+
+ printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev);
+
+ gpiochip_remove(&ucb->gc);
+
+ platform_set_drvdata(dev, NULL);
+ kfree(ucb);
+
+ return err;
+}
+
+static struct platform_driver bcm2708_gpio_driver = {
+ .probe = bcm2708_gpio_probe,
+ .remove = bcm2708_gpio_remove,
+ .driver = {
+ .name = "bcm2708_gpio"},
+};
+
+static int __init bcm2708_gpio_init(void)
+{
+ return platform_driver_register(&bcm2708_gpio_driver);
+}
+
+static void __exit bcm2708_gpio_exit(void)
+{
+ platform_driver_unregister(&bcm2708_gpio_driver);
+}
+
+module_init(bcm2708_gpio_init);
+module_exit(bcm2708_gpio_exit);
+
+MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-bcm2708/include/mach/gpio.h b/arch/arm/mach-bcm2708/include/mach/gpio.h
new file mode 100644
index 0000000..7965a97
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/gpio.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-bcm2708/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#define BCM2708_NR_GPIOS 54 // number of gpio lines
+
+#define gpio_to_irq(x) ((x) + GPIO_IRQ_START)
+#define irq_to_gpio(x) ((x) - GPIO_IRQ_START)
+
+#endif
diff --git a/include/linux/platform_data/bcm2708.h b/include/linux/platform_data/bcm2708.h
new file mode 100644
index 0000000..fb69624
--- /dev/null
+++ b/include/linux/platform_data/bcm2708.h
@@ -0,0 +1,23 @@
+/*
+ * include/linux/platform_data/bcm2708.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) 2014 Julian Scheel <julian@jusst.de>
+ *
+ */
+#ifndef __BCM2708_H_
+#define __BCM2708_H_
+
+typedef enum {
+ BCM2708_PULL_OFF,
+ BCM2708_PULL_UP,
+ BCM2708_PULL_DOWN
+} bcm2708_gpio_pull_t;
+
+extern int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
+ bcm2708_gpio_pull_t value);
+
+#endif
--
1.8.3.2

View file

@ -0,0 +1,218 @@
From cb3aee0334aa33348f1064301a6dff55cc31c84f Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 7 May 2013 22:20:24 +0100
Subject: [PATCH 003/114] Add quick config.
This is designed for quick compiling when developing.
No modules are needed and it includes all Pi specific drivers
---
arch/arm/configs/bcmrpi_quick_defconfig | 197 ++++++++++++++++++++++++++++++++
1 file changed, 197 insertions(+)
create mode 100644 arch/arm/configs/bcmrpi_quick_defconfig
diff --git a/arch/arm/configs/bcmrpi_quick_defconfig b/arch/arm/configs/bcmrpi_quick_defconfig
new file mode 100644
index 0000000..e5efe75
--- /dev/null
+++ b/arch/arm/configs/bcmrpi_quick_defconfig
@@ -0,0 +1,197 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_LOCALVERSION="-quick"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_BCM2708=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_CDC_NCM is not set
+CONFIG_USB_NET_SMSC95XX=y
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_TTY_PRINTK=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_BCM2708=y
+CONFIG_RAW_DRIVER=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_BCM2835=y
+CONFIG_WATCHDOG=y
+CONFIG_BCM2708_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_FB=y
+CONFIG_FB_BCM2708=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_BCM2835=y
+# CONFIG_SND_USB is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DWCOTG=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM2708=y
+CONFIG_MMC_SDHCI_BCM2708_DMA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FSCACHE=y
+CONFIG_CACHEFILES=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_KGDB=y
+CONFIG_KGDB_KDB=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_LIBCRC32C=y
--
1.8.3.2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,433 @@
From 633194396e40f919974dd8b81e97ddfea463b733 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 1 May 2013 19:54:32 +0100
Subject: [PATCH 005/114] bcm2708 watchdog driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
drivers/watchdog/Kconfig | 6 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/bcm2708_wdog.c | 382 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 389 insertions(+)
create mode 100644 drivers/watchdog/bcm2708_wdog.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index d0107d4..ff56894 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -452,6 +452,12 @@ config RETU_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called retu_wdt.
+config BCM2708_WDT
+ tristate "BCM2708 Watchdog"
+ depends on ARCH_BCM2708
+ help
+ Enables BCM2708 watchdog support.
+
config MOXART_WDT
tristate "MOXART watchdog"
depends on ARCH_MOXART
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index c569ec8..10e0665 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
+obj-$(CONFIG_BCM2708_WDT) += bcm2708_wdog.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o
obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o
diff --git a/drivers/watchdog/bcm2708_wdog.c b/drivers/watchdog/bcm2708_wdog.c
new file mode 100644
index 0000000..8a27d68
--- /dev/null
+++ b/drivers/watchdog/bcm2708_wdog.c
@@ -0,0 +1,382 @@
+/*
+ * Broadcom BCM2708 watchdog driver.
+ *
+ * (c) Copyright 2010 Broadcom Europe Ltd
+ *
+ * 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.
+ *
+ * BCM2708 watchdog driver. Loosely based on wdt driver.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <mach/platform.h>
+
+#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
+#define WDOG_TICKS_TO_SECS(x) ((x) >> 16)
+
+static unsigned long wdog_is_open;
+static uint32_t wdog_ticks; /* Ticks to load into wdog timer */
+static char expect_close;
+
+/*
+ * Module parameters
+ */
+
+#define WD_TIMO 10 /* Default heartbeat = 60 seconds */
+static int heartbeat = WD_TIMO; /* Heartbeat in seconds */
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+ "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default="
+ __MODULE_STRING(WD_TIMO) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static DEFINE_SPINLOCK(wdog_lock);
+
+/**
+ * Start the watchdog driver.
+ */
+
+static int wdog_start(unsigned long timeout)
+{
+ uint32_t cur;
+ unsigned long flags;
+ spin_lock_irqsave(&wdog_lock, flags);
+
+ /* enable the watchdog */
+ iowrite32(PM_PASSWORD | (timeout & PM_WDOG_TIME_SET),
+ __io_address(PM_WDOG));
+ cur = ioread32(__io_address(PM_RSTC));
+ iowrite32(PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) |
+ PM_RSTC_WRCFG_FULL_RESET, __io_address(PM_RSTC));
+
+ spin_unlock_irqrestore(&wdog_lock, flags);
+ return 0;
+}
+
+/**
+ * Stop the watchdog driver.
+ */
+
+static int wdog_stop(void)
+{
+ iowrite32(PM_PASSWORD | PM_RSTC_RESET, __io_address(PM_RSTC));
+ printk(KERN_INFO "watchdog stopped\n");
+ return 0;
+}
+
+/**
+ * Reload counter one with the watchdog heartbeat. We don't bother
+ * reloading the cascade counter.
+ */
+
+static void wdog_ping(void)
+{
+ wdog_start(wdog_ticks);
+}
+
+/**
+ * @t: the new heartbeat value that needs to be set.
+ *
+ * Set a new heartbeat value for the watchdog device. If the heartbeat
+ * value is incorrect we keep the old value and return -EINVAL. If
+ * successful we return 0.
+ */
+
+static int wdog_set_heartbeat(int t)
+{
+ if (t < 1 || t > WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET))
+ return -EINVAL;
+
+ heartbeat = t;
+ wdog_ticks = SECS_TO_WDOG_TICKS(t);
+ return 0;
+}
+
+/**
+ * @file: file handle to the watchdog
+ * @buf: buffer to write (unused as data does not matter here
+ * @count: count of bytes
+ * @ppos: pointer to the position to write. No seeks allowed
+ *
+ * A write to a watchdog device is defined as a keepalive signal.
+ *
+ * if 'nowayout' is set then normally a close() is ignored. But
+ * if you write 'V' first then the close() will stop the timer.
+ */
+
+static ssize_t wdog_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+ wdog_ping();
+ }
+ return count;
+}
+
+static int wdog_get_status(void)
+{
+ unsigned long flags;
+ int status = 0;
+ spin_lock_irqsave(&wdog_lock, flags);
+ /* FIXME: readback reset reason */
+ spin_unlock_irqrestore(&wdog_lock, flags);
+ return status;
+}
+
+static uint32_t wdog_get_remaining(void)
+{
+ uint32_t ret = ioread32(__io_address(PM_WDOG));
+ return ret & PM_WDOG_TIME_SET;
+}
+
+/**
+ * @file: file handle to the device
+ * @cmd: watchdog command
+ * @arg: argument pointer
+ *
+ * The watchdog API defines a common set of functions for all watchdogs
+ * according to their available features. We only actually usefully support
+ * querying capabilities and current status.
+ */
+
+static long wdog_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_heartbeat;
+ int status;
+ int options;
+ uint32_t remaining;
+
+ struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT|
+ WDIOF_MAGICCLOSE|
+ WDIOF_KEEPALIVEPING,
+ .firmware_version = 1,
+ .identity = "BCM2708",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+ case WDIOC_GETSTATUS:
+ status = wdog_get_status();
+ return put_user(status, p);
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+ case WDIOC_KEEPALIVE:
+ wdog_ping();
+ return 0;
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_heartbeat, p))
+ return -EFAULT;
+ if (wdog_set_heartbeat(new_heartbeat))
+ return -EINVAL;
+ wdog_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ return put_user(heartbeat, p);
+ case WDIOC_GETTIMELEFT:
+ remaining = WDOG_TICKS_TO_SECS(wdog_get_remaining());
+ return put_user(remaining, p);
+ case WDIOC_SETOPTIONS:
+ if (get_user(options, p))
+ return -EFAULT;
+ if (options & WDIOS_DISABLECARD)
+ wdog_stop();
+ if (options & WDIOS_ENABLECARD)
+ wdog_start(wdog_ticks);
+ return 0;
+ default:
+ return -ENOTTY;
+ }
+}
+
+/**
+ * @inode: inode of device
+ * @file: file handle to device
+ *
+ * The watchdog device has been opened. The watchdog device is single
+ * open and on opening we load the counters.
+ */
+
+static int wdog_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &wdog_is_open))
+ return -EBUSY;
+ /*
+ * Activate
+ */
+ wdog_start(wdog_ticks);
+ return nonseekable_open(inode, file);
+}
+
+/**
+ * @inode: inode to board
+ * @file: file handle to board
+ *
+ * The watchdog has a configurable API. There is a religious dispute
+ * between people who want their watchdog to be able to shut down and
+ * those who want to be sure if the watchdog manager dies the machine
+ * reboots. In the former case we disable the counters, in the latter
+ * case you have to open it again very soon.
+ */
+
+static int wdog_release(struct inode *inode, struct file *file)
+{
+ if (expect_close == 42) {
+ wdog_stop();
+ } else {
+ printk(KERN_CRIT
+ "wdt: WDT device closed unexpectedly. WDT will not stop!\n");
+ wdog_ping();
+ }
+ clear_bit(0, &wdog_is_open);
+ expect_close = 0;
+ return 0;
+}
+
+/**
+ * @this: our notifier block
+ * @code: the event being reported
+ * @unused: unused
+ *
+ * Our notifier is called on system shutdowns. Turn the watchdog
+ * off so that it does not fire during the next reboot.
+ */
+
+static int wdog_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT)
+ wdog_stop();
+ return NOTIFY_DONE;
+}
+
+/*
+ * Kernel Interfaces
+ */
+
+
+static const struct file_operations wdog_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = wdog_write,
+ .unlocked_ioctl = wdog_ioctl,
+ .open = wdog_open,
+ .release = wdog_release,
+};
+
+static struct miscdevice wdog_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &wdog_fops,
+};
+
+/*
+ * The WDT card needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block wdog_notifier = {
+ .notifier_call = wdog_notify_sys,
+};
+
+/**
+ * cleanup_module:
+ *
+ * Unload the watchdog. You cannot do this with any file handles open.
+ * If your watchdog is set to continue ticking on close and you unload
+ * it, well it keeps ticking. We won't get the interrupt but the board
+ * will not touch PC memory so all is fine. You just have to load a new
+ * module in 60 seconds or reboot.
+ */
+
+static void __exit wdog_exit(void)
+{
+ misc_deregister(&wdog_miscdev);
+ unregister_reboot_notifier(&wdog_notifier);
+}
+
+static int __init wdog_init(void)
+{
+ int ret;
+
+ /* Check that the heartbeat value is within it's range;
+ if not reset to the default */
+ if (wdog_set_heartbeat(heartbeat)) {
+ wdog_set_heartbeat(WD_TIMO);
+ printk(KERN_INFO "bcm2708_wdog: heartbeat value must be "
+ "0 < heartbeat < %d, using %d\n",
+ WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
+ WD_TIMO);
+ }
+
+ ret = register_reboot_notifier(&wdog_notifier);
+ if (ret) {
+ printk(KERN_ERR
+ "wdt: cannot register reboot notifier (err=%d)\n", ret);
+ goto out_reboot;
+ }
+
+ ret = misc_register(&wdog_miscdev);
+ if (ret) {
+ printk(KERN_ERR
+ "wdt: cannot register miscdev on minor=%d (err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto out_misc;
+ }
+
+ printk(KERN_INFO "bcm2708 watchdog, heartbeat=%d sec (nowayout=%d)\n",
+ heartbeat, nowayout);
+ return 0;
+
+out_misc:
+ unregister_reboot_notifier(&wdog_notifier);
+out_reboot:
+ return ret;
+}
+
+module_init(wdog_init);
+module_exit(wdog_exit);
+
+MODULE_AUTHOR("Luke Diamand");
+MODULE_DESCRIPTION("Driver for BCM2708 watchdog");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS_MISCDEV(TEMP_MINOR);
+MODULE_LICENSE("GPL");
--
1.8.3.2

View file

@ -0,0 +1,214 @@
From 91fca9dd33742a38061dc9e949e4e88b9d5f645b Mon Sep 17 00:00:00 2001
From: Harm Hanemaaijer <fgenfb@yahoo.com>
Date: Thu, 20 Jun 2013 20:21:39 +0200
Subject: [PATCH 007/114] Speed up console framebuffer imageblit function
Especially on platforms with a slower CPU but a relatively high
framebuffer fill bandwidth, like current ARM devices, the existing
console monochrome imageblit function used to draw console text is
suboptimal for common pixel depths such as 16bpp and 32bpp. The existing
code is quite general and can deal with several pixel depths. By creating
special case functions for 16bpp and 32bpp, by far the most common pixel
formats used on modern systems, a significant speed-up is attained
which can be readily felt on ARM-based devices like the Raspberry Pi
and the Allwinner platform, but should help any platform using the
fb layer.
The special case functions allow constant folding, eliminating a number
of instructions including divide operations, and allow the use of an
unrolled loop, eliminating instructions with a variable shift size,
reducing source memory access instructions, and eliminating excessive
branching. These unrolled loops also allow much better code optimization
by the C compiler. The code that selects which optimized variant is used
is also simplified, eliminating integer divide instructions.
The speed-up, measured by timing 'cat file.txt' in the console, varies
between 40% and 70%, when testing on the Raspberry Pi and Allwinner
ARM-based platforms, depending on font size and the pixel depth, with
the greater benefit for 32bpp.
Signed-off-by: Harm Hanemaaijer <fgenfb@yahoo.com>
---
drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++--
1 file changed, 147 insertions(+), 5 deletions(-)
diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c
index a2bb276..436494f 100644
--- a/drivers/video/fbdev/core/cfbimgblt.c
+++ b/drivers/video/fbdev/core/cfbimgblt.c
@@ -28,6 +28,11 @@
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013:
+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are
+ * significantly faster than the previous implementation.
+ * - Simplify the fast/slow_imageblit selection code, avoiding integer
+ * divides.
*/
#include <linux/module.h>
#include <linux/string.h>
@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
}
}
+/*
+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded
+ * into the code, main loop unrolled.
+ */
+
+static inline void fast_imageblit16(const struct fb_image *image,
+ struct fb_info *p, u8 __iomem * dst1,
+ u32 fgcolor, u32 bgcolor)
+{
+ u32 fgx = fgcolor, bgx = bgcolor;
+ u32 spitch = (image->width + 7) / 8;
+ u32 end_mask, eorx;
+ const char *s = image->data, *src;
+ u32 __iomem *dst;
+ const u32 *tab = NULL;
+ int i, j, k;
+
+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le;
+
+ fgx <<= 16;
+ bgx <<= 16;
+ fgx |= fgcolor;
+ bgx |= bgcolor;
+
+ eorx = fgx ^ bgx;
+ k = image->width / 2;
+
+ for (i = image->height; i--;) {
+ dst = (u32 __iomem *) dst1;
+ src = s;
+
+ j = k;
+ while (j >= 4) {
+ u8 bits = *src;
+ end_mask = tab[(bits >> 6) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 4) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 2) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[bits & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ src++;
+ j -= 4;
+ }
+ if (j != 0) {
+ u8 bits = *src;
+ end_mask = tab[(bits >> 6) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ if (j >= 2) {
+ end_mask = tab[(bits >> 4) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ if (j == 3) {
+ end_mask = tab[(bits >> 2) & 3];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
+ }
+ }
+ }
+ dst1 += p->fix.line_length;
+ s += spitch;
+ }
+}
+
+/*
+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded
+ * into the code, main loop unrolled.
+ */
+
+static inline void fast_imageblit32(const struct fb_image *image,
+ struct fb_info *p, u8 __iomem * dst1,
+ u32 fgcolor, u32 bgcolor)
+{
+ u32 fgx = fgcolor, bgx = bgcolor;
+ u32 spitch = (image->width + 7) / 8;
+ u32 end_mask, eorx;
+ const char *s = image->data, *src;
+ u32 __iomem *dst;
+ const u32 *tab = NULL;
+ int i, j, k;
+
+ tab = cfb_tab32;
+
+ eorx = fgx ^ bgx;
+ k = image->width;
+
+ for (i = image->height; i--;) {
+ dst = (u32 __iomem *) dst1;
+ src = s;
+
+ j = k;
+ while (j >= 8) {
+ u8 bits = *src;
+ end_mask = tab[(bits >> 7) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 6) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 5) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 4) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 3) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 2) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[(bits >> 1) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ end_mask = tab[bits & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ src++;
+ j -= 8;
+ }
+ if (j != 0) {
+ u32 bits = (u32) * src;
+ while (j > 1) {
+ end_mask = tab[(bits >> 7) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
+ bits <<= 1;
+ j--;
+ }
+ end_mask = tab[(bits >> 7) & 1];
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
+ }
+ dst1 += p->fix.line_length;
+ s += spitch;
+ }
+}
+
void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
{
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
bgcolor = image->bg_color;
}
- if (32 % bpp == 0 && !start_index && !pitch_index &&
- ((width & (32/bpp-1)) == 0) &&
- bpp >= 8 && bpp <= 32)
- fast_imageblit(image, p, dst1, fgcolor, bgcolor);
- else
+ if (!start_index && !pitch_index) {
+ if (bpp == 32)
+ fast_imageblit32(image, p, dst1, fgcolor,
+ bgcolor);
+ else if (bpp == 16 && (width & 1) == 0)
+ fast_imageblit16(image, p, dst1, fgcolor,
+ bgcolor);
+ else if (bpp == 8 && (width & 3) == 0)
+ fast_imageblit(image, p, dst1, fgcolor,
+ bgcolor);
+ else
+ slow_imageblit(image, p, dst1, fgcolor,
+ bgcolor,
+ start_index, pitch_index);
+ } else
slow_imageblit(image, p, dst1, fgcolor, bgcolor,
start_index, pitch_index);
} else
--
1.8.3.2

View file

@ -0,0 +1,98 @@
From f67ad61f5999035fad1610d00a966989f34e3ce5 Mon Sep 17 00:00:00 2001
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Date: Mon, 17 Jun 2013 13:32:11 +0300
Subject: [PATCH 008/114] fbdev: add FBIOCOPYAREA ioctl
Based on the patch authored by Ali Gholami Rudi at
https://lkml.org/lkml/2009/7/13/153
Provide an ioctl for userspace applications, but only if this operation
is hardware accelerated (otherwide it does not make any sense).
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
---
drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++
include/uapi/linux/fb.h | 5 +++++
2 files changed, 35 insertions(+)
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 0705d88..771992a 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank)
}
EXPORT_SYMBOL(fb_blank);
+static int fb_copyarea_user(struct fb_info *info,
+ struct fb_copyarea *copy)
+{
+ int ret = 0;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ if (copy->dx + copy->width > info->var.xres ||
+ copy->sx + copy->width > info->var.xres ||
+ copy->dy + copy->height > info->var.yres ||
+ copy->sy + copy->height > info->var.yres) {
+ ret = -EINVAL;
+ goto out;
+ }
+ info->fbops->fb_copyarea(info, copy);
+out:
+ unlock_fb_info(info);
+ return ret;
+}
+
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
struct fb_cmap cmap_from;
struct fb_cmap_user cmap;
struct fb_event event;
+ struct fb_copyarea copy;
void __user *argp = (void __user *)arg;
long ret = 0;
@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unlock_fb_info(info);
console_unlock();
break;
+ case FBIOCOPYAREA:
+ if (info->flags & FBINFO_HWACCEL_COPYAREA) {
+ /* only provide this ioctl if it is accelerated */
+ if (copy_from_user(&copy, argp, sizeof(copy)))
+ return -EFAULT;
+ ret = fb_copyarea_user(info, &copy);
+ break;
+ }
+ /* fall through */
default:
if (!lock_fb_info(info))
return -ENODEV;
@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
case FBIOPAN_DISPLAY:
case FBIOGET_CON2FBMAP:
case FBIOPUT_CON2FBMAP:
+ case FBIOCOPYAREA:
arg = (unsigned long) compat_ptr(arg);
case FBIOBLANK:
ret = do_fb_ioctl(info, cmd, arg);
diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
index fb795c3..fa72af0 100644
--- a/include/uapi/linux/fb.h
+++ b/include/uapi/linux/fb.h
@@ -34,6 +34,11 @@
#define FBIOPUT_MODEINFO 0x4617
#define FBIOGET_DISPINFO 0x4618
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+/*
+ * HACK: use 'z' in order not to clash with any other ioctl numbers which might
+ * be concurrently added to the mainline kernel
+ */
+#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea)
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
--
1.8.3.2

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
From e0412853d9f9e12fc7d8a3125cc3b4a62d19007d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 12 May 2014 15:12:02 +0100
Subject: [PATCH 011/114] vchiq: Avoid high load when blocked and unkillable
vchiq: Include SIGSTOP and SIGCONT in list of signals not-masked by vchiq to allow gdb to work
---
.../interface/vchiq_arm/vchiq_2835_arm.c | 1 +
.../vc04_services/interface/vchiq_arm/vchiq_arm.c | 1 +
.../interface/vchiq_arm/vchiq_connected.c | 1 +
.../vc04_services/interface/vchiq_arm/vchiq_core.c | 1 +
.../interface/vchiq_arm/vchiq_kern_lib.c | 1 +
.../interface/vchiq_arm/vchiq_killable.h | 69 ++++++++++++++++++++++
.../vc04_services/interface/vchiq_arm/vchiq_util.c | 1 +
7 files changed, 75 insertions(+)
create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_killable.h
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index b3bdaa2..7e7b09f 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -56,6 +56,7 @@
#include "vchiq_arm.h"
#include "vchiq_2835.h"
#include "vchiq_connected.h"
+#include "vchiq_killable.h"
#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2)
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 2596818..3e328ab 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -50,6 +50,7 @@
#include "vchiq_ioctl.h"
#include "vchiq_arm.h"
#include "vchiq_debugfs.h"
+#include "vchiq_killable.h"
#define DEVICE_NAME "vchiq"
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
index 65f4b52..5efc62f 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
@@ -33,6 +33,7 @@
#include "vchiq_connected.h"
#include "vchiq_core.h"
+#include "vchiq_killable.h"
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
index f962027..14a4155 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -32,6 +32,7 @@
*/
#include "vchiq_core.h"
+#include "vchiq_killable.h"
#define VCHIQ_SLOT_HANDLER_STACK 8192
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
index be9735f..5a4182e 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
@@ -39,6 +39,7 @@
#include "vchiq_core.h"
#include "vchiq_arm.h"
+#include "vchiq_killable.h"
/* ---- Public Variables ------------------------------------------------- */
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_killable.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_killable.h
new file mode 100644
index 0000000..335446e
--- /dev/null
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_killable.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2, as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_KILLABLE_H
+#define VCHIQ_KILLABLE_H
+
+#include <linux/mutex.h>
+#include <linux/semaphore.h>
+
+#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTRAP) | sigmask(SIGSTOP) | sigmask(SIGCONT))
+
+static inline int __must_check down_interruptible_killable(struct semaphore *sem)
+{
+ /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */
+ int ret;
+ sigset_t blocked, oldset;
+ siginitsetinv(&blocked, SHUTDOWN_SIGS);
+ sigprocmask(SIG_SETMASK, &blocked, &oldset);
+ ret = down_interruptible(sem);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ return ret;
+}
+#define down_interruptible down_interruptible_killable
+
+
+static inline int __must_check mutex_lock_interruptible_killable(struct mutex *lock)
+{
+ /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */
+ int ret;
+ sigset_t blocked, oldset;
+ siginitsetinv(&blocked, SHUTDOWN_SIGS);
+ sigprocmask(SIG_SETMASK, &blocked, &oldset);
+ ret = mutex_lock_interruptible(lock);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ return ret;
+}
+#define mutex_lock_interruptible mutex_lock_interruptible_killable
+
+#endif
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
index c2eefef..05e7979 100644
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
@@ -32,6 +32,7 @@
*/
#include "vchiq_util.h"
+#include "vchiq_killable.h"
static inline int is_pow2(int i)
{
--
1.8.3.2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,172 @@
From 225e1250dfcec7b09493b6a86bdeaab9f2669221 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:51:55 +0100
Subject: [PATCH 014/114] Add hwrng (hardware random number generator) driver
---
drivers/char/hw_random/Kconfig | 11 ++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/bcm2708-rng.c | 118 +++++++++++++++++++++++++++++++++++
3 files changed, 130 insertions(+)
create mode 100755 drivers/char/hw_random/bcm2708-rng.c
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 91a04ae..0d2ca0d 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -320,6 +320,17 @@ config HW_RANDOM_TPM
If unsure, say Y.
+config HW_RANDOM_BCM2708
+ tristate "BCM2708 generic true random number generator support"
+ depends on HW_RANDOM && ARCH_BCM2708
+ ---help---
+ This driver provides the kernel-side support for the BCM2708 hardware.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm2708-rng.
+
+ If unsure, say N.
+
config HW_RANDOM_MSM
tristate "Qualcomm SoCs Random Number Generator support"
depends on HW_RANDOM && ARCH_QCOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 0b4cd57..78b019c 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+obj-$(CONFIG_HW_RANDOM_BCM2708) += bcm2708-rng.o
obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
diff --git a/drivers/char/hw_random/bcm2708-rng.c b/drivers/char/hw_random/bcm2708-rng.c
new file mode 100755
index 0000000..340f004
--- /dev/null
+++ b/drivers/char/hw_random/bcm2708-rng.c
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2, as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/hw_random.h>
+#include <linux/printk.h>
+
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#define RNG_CTRL (0x0)
+#define RNG_STATUS (0x4)
+#define RNG_DATA (0x8)
+#define RNG_FF_THRESHOLD (0xc)
+
+/* enable rng */
+#define RNG_RBGEN 0x1
+/* double speed, less random mode */
+#define RNG_RBG2X 0x2
+
+/* the initial numbers generated are "less random" so will be discarded */
+#define RNG_WARMUP_COUNT 0x40000
+
+static int bcm2708_rng_data_read(struct hwrng *rng, u32 *buffer)
+{
+ void __iomem *rng_base = (void __iomem *)rng->priv;
+ unsigned words;
+ /* wait for a random number to be in fifo */
+ do {
+ words = __raw_readl(rng_base + RNG_STATUS)>>24;
+ }
+ while (words == 0);
+ /* read the random number */
+ *buffer = __raw_readl(rng_base + RNG_DATA);
+ return 4;
+}
+
+static struct hwrng bcm2708_rng_ops = {
+ .name = "bcm2708",
+ .data_read = bcm2708_rng_data_read,
+};
+
+static int __init bcm2708_rng_init(void)
+{
+ void __iomem *rng_base;
+ int err;
+
+ /* map peripheral */
+ rng_base = ioremap(RNG_BASE, 0x10);
+ pr_info("bcm2708_rng_init=%p\n", rng_base);
+ if (!rng_base) {
+ pr_err("bcm2708_rng_init failed to ioremap\n");
+ return -ENOMEM;
+ }
+ bcm2708_rng_ops.priv = (unsigned long)rng_base;
+
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+
+ /* register driver */
+ err = hwrng_register(&bcm2708_rng_ops);
+ if (err) {
+ pr_err("bcm2708_rng_init hwrng_register()=%d\n", err);
+ iounmap(rng_base);
+ }
+ return err;
+}
+
+static void __exit bcm2708_rng_exit(void)
+{
+ void __iomem *rng_base = (void __iomem *)bcm2708_rng_ops.priv;
+ pr_info("bcm2708_rng_exit\n");
+ /* disable rng hardware */
+ __raw_writel(0, rng_base + RNG_CTRL);
+ /* unregister driver */
+ hwrng_unregister(&bcm2708_rng_ops);
+ iounmap(rng_base);
+}
+
+module_init(bcm2708_rng_init);
+module_exit(bcm2708_rng_exit);
+
+MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL and additional rights");
--
1.8.3.2

View file

@ -0,0 +1,737 @@
From 96fbef3b8f8ab61f7f32d52b54d7993117a5fdbc Mon Sep 17 00:00:00 2001
From: Aron Szabo <aron@aron.ws>
Date: Sat, 16 Jun 2012 12:15:55 +0200
Subject: [PATCH 015/114] lirc: added support for RaspberryPi GPIO
lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others
See: https://github.com/raspberrypi/linux/issues/525
lirc: Remove restriction on gpio pins that can be used with lirc
Compute Module, for example could use different pins
lirc_rpi: Add parameter to specify input pin pull
Depending on the connected IR circuitry it might be desirable to change the
gpios internal pull from it pull-down default behaviour. Add a module
parameter to allow the user to set it explicitly.
Signed-off-by: Julian Scheel <julian@jusst.de>
lirc-rpi: Use the higher-level irq control functions
This module used to access the irq_chip methods of the
gpio controller directly, rather than going through the
standard enable_irq/irq_set_irq_type functions. This
caused problems on pinctrl-bcm2835 which only implements
the irq_enable/disable methods and not irq_unmask/mask.
lirc-rpi: Correct the interrupt usage
1) Correct the use of enable_irq (i.e. don't call it so often)
2) Correct the shutdown sequence.
3) Avoid a bcm2708_gpio driver quirk by setting the irq flags earlier
---
drivers/staging/media/lirc/Kconfig | 6 +
drivers/staging/media/lirc/Makefile | 1 +
drivers/staging/media/lirc/lirc_rpi.c | 659 ++++++++++++++++++++++++++++++++++
3 files changed, 666 insertions(+)
create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index e60a59f..6b7ff70 100644
--- a/drivers/staging/media/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
@@ -38,6 +38,12 @@ config LIRC_PARALLEL
help
Driver for Homebrew Parallel Port Receivers
+config LIRC_RPI
+ tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
+ depends on LIRC
+ help
+ Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
+
config LIRC_SASEM
tristate "Sasem USB IR Remote"
depends on LIRC && USB
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index b90fcab..2b227fd 100644
--- a/drivers/staging/media/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
+obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c
new file mode 100644
index 0000000..c688364
--- /dev/null
+++ b/drivers/staging/media/lirc/lirc_rpi.c
@@ -0,0 +1,659 @@
+/*
+ * lirc_rpi.c
+ *
+ * lirc_rpi - Device driver that records pulse- and pause-lengths
+ * (space-lengths) (just like the lirc_serial driver does)
+ * between GPIO interrupt events on the Raspberry Pi.
+ * Lots of code has been taken from the lirc_serial module,
+ * so I would like say thanks to the authors.
+ *
+ * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
+ * Michael Bishop <cleverca22@gmail.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
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <media/lirc.h>
+#include <media/lirc_dev.h>
+#include <mach/gpio.h>
+#include <linux/gpio.h>
+
+#include <linux/platform_data/bcm2708.h>
+
+#define LIRC_DRIVER_NAME "lirc_rpi"
+#define RBUF_LEN 256
+#define LIRC_TRANSMITTER_LATENCY 50
+
+#ifndef MAX_UDELAY_MS
+#define MAX_UDELAY_US 5000
+#else
+#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
+#endif
+
+#define dprintk(fmt, args...) \
+ do { \
+ if (debug) \
+ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
+ fmt, ## args); \
+ } while (0)
+
+/* module parameters */
+
+/* set the default GPIO input pin */
+static int gpio_in_pin = 18;
+/* set the default pull behaviour for input pin */
+static int gpio_in_pull = BCM2708_PULL_DOWN;
+/* set the default GPIO output pin */
+static int gpio_out_pin = 17;
+/* enable debugging messages */
+static bool debug;
+/* -1 = auto, 0 = active high, 1 = active low */
+static int sense = -1;
+/* use softcarrier by default */
+static bool softcarrier = 1;
+/* 0 = do not invert output, 1 = invert output */
+static bool invert = 0;
+
+struct gpio_chip *gpiochip;
+static int irq_num;
+
+/* forward declarations */
+static long send_pulse(unsigned long length);
+static void send_space(long length);
+static void lirc_rpi_exit(void);
+
+static struct platform_device *lirc_rpi_dev;
+static struct timeval lasttv = { 0, 0 };
+static struct lirc_buffer rbuf;
+static spinlock_t lock;
+
+/* initialized/set in init_timing_params() */
+static unsigned int freq = 38000;
+static unsigned int duty_cycle = 50;
+static unsigned long period;
+static unsigned long pulse_width;
+static unsigned long space_width;
+
+static void safe_udelay(unsigned long usecs)
+{
+ while (usecs > MAX_UDELAY_US) {
+ udelay(MAX_UDELAY_US);
+ usecs -= MAX_UDELAY_US;
+ }
+ udelay(usecs);
+}
+
+static int init_timing_params(unsigned int new_duty_cycle,
+ unsigned int new_freq)
+{
+ if (1000 * 1000000L / new_freq * new_duty_cycle / 100 <=
+ LIRC_TRANSMITTER_LATENCY)
+ return -EINVAL;
+ if (1000 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
+ LIRC_TRANSMITTER_LATENCY)
+ return -EINVAL;
+ duty_cycle = new_duty_cycle;
+ freq = new_freq;
+ period = 1000 * 1000000L / freq;
+ pulse_width = period * duty_cycle / 100;
+ space_width = period - pulse_width;
+ dprintk("in init_timing_params, freq=%d pulse=%ld, "
+ "space=%ld\n", freq, pulse_width, space_width);
+ return 0;
+}
+
+static long send_pulse_softcarrier(unsigned long length)
+{
+ int flag;
+ unsigned long actual, target;
+ unsigned long actual_us, initial_us, target_us;
+
+ length *= 1000;
+
+ actual = 0; target = 0; flag = 0;
+ read_current_timer(&actual_us);
+
+ while (actual < length) {
+ if (flag) {
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
+ target += space_width;
+ } else {
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
+ target += pulse_width;
+ }
+ initial_us = actual_us;
+ target_us = actual_us + (target - actual) / 1000;
+ /*
+ * Note - we've checked in ioctl that the pulse/space
+ * widths are big enough so that d is > 0
+ */
+ if ((int)(target_us - actual_us) > 0)
+ udelay(target_us - actual_us);
+ read_current_timer(&actual_us);
+ actual += (actual_us - initial_us) * 1000;
+ flag = !flag;
+ }
+ return (actual-length) / 1000;
+}
+
+static long send_pulse(unsigned long length)
+{
+ if (length <= 0)
+ return 0;
+
+ if (softcarrier) {
+ return send_pulse_softcarrier(length);
+ } else {
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
+ safe_udelay(length);
+ return 0;
+ }
+}
+
+static void send_space(long length)
+{
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
+ if (length <= 0)
+ return;
+ safe_udelay(length);
+}
+
+static void rbwrite(int l)
+{
+ if (lirc_buffer_full(&rbuf)) {
+ /* no new signals will be accepted */
+ dprintk("Buffer overrun\n");
+ return;
+ }
+ lirc_buffer_write(&rbuf, (void *)&l);
+}
+
+static void frbwrite(int l)
+{
+ /* simple noise filter */
+ static int pulse, space;
+ static unsigned int ptr;
+
+ if (ptr > 0 && (l & PULSE_BIT)) {
+ pulse += l & PULSE_MASK;
+ if (pulse > 250) {
+ rbwrite(space);
+ rbwrite(pulse | PULSE_BIT);
+ ptr = 0;
+ pulse = 0;
+ }
+ return;
+ }
+ if (!(l & PULSE_BIT)) {
+ if (ptr == 0) {
+ if (l > 20000) {
+ space = l;
+ ptr++;
+ return;
+ }
+ } else {
+ if (l > 20000) {
+ space += pulse;
+ if (space > PULSE_MASK)
+ space = PULSE_MASK;
+ space += l;
+ if (space > PULSE_MASK)
+ space = PULSE_MASK;
+ pulse = 0;
+ return;
+ }
+ rbwrite(space);
+ rbwrite(pulse | PULSE_BIT);
+ ptr = 0;
+ pulse = 0;
+ }
+ }
+ rbwrite(l);
+}
+
+static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
+{
+ struct timeval tv;
+ long deltv;
+ int data;
+ int signal;
+
+ /* use the GPIO signal level */
+ signal = gpiochip->get(gpiochip, gpio_in_pin);
+
+ if (sense != -1) {
+ /* get current time */
+ do_gettimeofday(&tv);
+
+ /* calc time since last interrupt in microseconds */
+ deltv = tv.tv_sec-lasttv.tv_sec;
+ if (tv.tv_sec < lasttv.tv_sec ||
+ (tv.tv_sec == lasttv.tv_sec &&
+ tv.tv_usec < lasttv.tv_usec)) {
+ printk(KERN_WARNING LIRC_DRIVER_NAME
+ ": AIEEEE: your clock just jumped backwards\n");
+ printk(KERN_WARNING LIRC_DRIVER_NAME
+ ": %d %d %lx %lx %lx %lx\n", signal, sense,
+ tv.tv_sec, lasttv.tv_sec,
+ tv.tv_usec, lasttv.tv_usec);
+ data = PULSE_MASK;
+ } else if (deltv > 15) {
+ data = PULSE_MASK; /* really long time */
+ if (!(signal^sense)) {
+ /* sanity check */
+ printk(KERN_WARNING LIRC_DRIVER_NAME
+ ": AIEEEE: %d %d %lx %lx %lx %lx\n",
+ signal, sense, tv.tv_sec, lasttv.tv_sec,
+ tv.tv_usec, lasttv.tv_usec);
+ /*
+ * detecting pulse while this
+ * MUST be a space!
+ */
+ sense = sense ? 0 : 1;
+ }
+ } else {
+ data = (int) (deltv*1000000 +
+ (tv.tv_usec - lasttv.tv_usec));
+ }
+ frbwrite(signal^sense ? data : (data|PULSE_BIT));
+ lasttv = tv;
+ wake_up_interruptible(&rbuf.wait_poll);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int is_right_chip(struct gpio_chip *chip, void *data)
+{
+ dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
+
+ if (strcmp(data, chip->label) == 0)
+ return 1;
+ return 0;
+}
+
+static int init_port(void)
+{
+ int i, nlow, nhigh, ret;
+
+ gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
+
+ if (!gpiochip)
+ return -ENODEV;
+
+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
+ printk(KERN_ALERT LIRC_DRIVER_NAME
+ ": cant claim gpio pin %d\n", gpio_out_pin);
+ ret = -ENODEV;
+ goto exit_init_port;
+ }
+
+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
+ printk(KERN_ALERT LIRC_DRIVER_NAME
+ ": cant claim gpio pin %d\n", gpio_in_pin);
+ ret = -ENODEV;
+ goto exit_gpio_free_out_pin;
+ }
+
+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull);
+ gpiochip->direction_input(gpiochip, gpio_in_pin);
+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
+
+ irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
+ dprintk("to_irq %d\n", irq_num);
+
+ /* if pin is high, then this must be an active low receiver. */
+ if (sense == -1) {
+ /* wait 1/2 sec for the power supply */
+ msleep(500);
+
+ /*
+ * probe 9 times every 0.04s, collect "votes" for
+ * active high/low
+ */
+ nlow = 0;
+ nhigh = 0;
+ for (i = 0; i < 9; i++) {
+ if (gpiochip->get(gpiochip, gpio_in_pin))
+ nlow++;
+ else
+ nhigh++;
+ msleep(40);
+ }
+ sense = (nlow >= nhigh ? 1 : 0);
+ printk(KERN_INFO LIRC_DRIVER_NAME
+ ": auto-detected active %s receiver on GPIO pin %d\n",
+ sense ? "low" : "high", gpio_in_pin);
+ } else {
+ printk(KERN_INFO LIRC_DRIVER_NAME
+ ": manually using active %s receiver on GPIO pin %d\n",
+ sense ? "low" : "high", gpio_in_pin);
+ }
+
+ return 0;
+
+ exit_gpio_free_out_pin:
+ gpio_free(gpio_out_pin);
+
+ exit_init_port:
+ return ret;
+}
+
+// called when the character device is opened
+static int set_use_inc(void *data)
+{
+ int result;
+
+ /* initialize timestamp */
+ do_gettimeofday(&lasttv);
+
+ result = request_irq(irq_num,
+ (irq_handler_t) irq_handler,
+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+ LIRC_DRIVER_NAME, (void*) 0);
+
+ switch (result) {
+ case -EBUSY:
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": IRQ %d is busy\n",
+ irq_num);
+ return -EBUSY;
+ case -EINVAL:
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": Bad irq number or handler\n");
+ return -EINVAL;
+ default:
+ dprintk("Interrupt %d obtained\n",
+ irq_num);
+ break;
+ };
+
+ /* initialize pulse/space widths */
+ init_timing_params(duty_cycle, freq);
+
+ return 0;
+}
+
+static void set_use_dec(void *data)
+{
+ /* GPIO Pin Falling/Rising Edge Detect Disable */
+ irq_set_irq_type(irq_num, 0);
+ disable_irq(irq_num);
+
+ free_irq(irq_num, (void *) 0);
+
+ dprintk(KERN_INFO LIRC_DRIVER_NAME
+ ": freed IRQ %d\n", irq_num);
+}
+
+static ssize_t lirc_write(struct file *file, const char *buf,
+ size_t n, loff_t *ppos)
+{
+ int i, count;
+ unsigned long flags;
+ long delta = 0;
+ int *wbuf;
+
+ count = n / sizeof(int);
+ if (n % sizeof(int) || count % 2 == 0)
+ return -EINVAL;
+ wbuf = memdup_user(buf, n);
+ if (IS_ERR(wbuf))
+ return PTR_ERR(wbuf);
+ spin_lock_irqsave(&lock, flags);
+
+ for (i = 0; i < count; i++) {
+ if (i%2)
+ send_space(wbuf[i] - delta);
+ else
+ delta = send_pulse(wbuf[i]);
+ }
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
+
+ spin_unlock_irqrestore(&lock, flags);
+ kfree(wbuf);
+ return n;
+}
+
+static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ int result;
+ __u32 value;
+
+ switch (cmd) {
+ case LIRC_GET_SEND_MODE:
+ return -ENOIOCTLCMD;
+ break;
+
+ case LIRC_SET_SEND_MODE:
+ result = get_user(value, (__u32 *) arg);
+ if (result)
+ return result;
+ /* only LIRC_MODE_PULSE supported */
+ if (value != LIRC_MODE_PULSE)
+ return -ENOSYS;
+ break;
+
+ case LIRC_GET_LENGTH:
+ return -ENOSYS;
+ break;
+
+ case LIRC_SET_SEND_DUTY_CYCLE:
+ dprintk("SET_SEND_DUTY_CYCLE\n");
+ result = get_user(value, (__u32 *) arg);
+ if (result)
+ return result;
+ if (value <= 0 || value > 100)
+ return -EINVAL;
+ return init_timing_params(value, freq);
+ break;
+
+ case LIRC_SET_SEND_CARRIER:
+ dprintk("SET_SEND_CARRIER\n");
+ result = get_user(value, (__u32 *) arg);
+ if (result)
+ return result;
+ if (value > 500000 || value < 20000)
+ return -EINVAL;
+ return init_timing_params(duty_cycle, value);
+ break;
+
+ default:
+ return lirc_dev_fop_ioctl(filep, cmd, arg);
+ }
+ return 0;
+}
+
+static const struct file_operations lirc_fops = {
+ .owner = THIS_MODULE,
+ .write = lirc_write,
+ .unlocked_ioctl = lirc_ioctl,
+ .read = lirc_dev_fop_read,
+ .poll = lirc_dev_fop_poll,
+ .open = lirc_dev_fop_open,
+ .release = lirc_dev_fop_close,
+ .llseek = no_llseek,
+};
+
+static struct lirc_driver driver = {
+ .name = LIRC_DRIVER_NAME,
+ .minor = -1,
+ .code_length = 1,
+ .sample_rate = 0,
+ .data = NULL,
+ .add_to_buf = NULL,
+ .rbuf = &rbuf,
+ .set_use_inc = set_use_inc,
+ .set_use_dec = set_use_dec,
+ .fops = &lirc_fops,
+ .dev = NULL,
+ .owner = THIS_MODULE,
+};
+
+static struct platform_driver lirc_rpi_driver = {
+ .driver = {
+ .name = LIRC_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init lirc_rpi_init(void)
+{
+ int result;
+
+ /* Init read buffer. */
+ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
+ if (result < 0)
+ return -ENOMEM;
+
+ result = platform_driver_register(&lirc_rpi_driver);
+ if (result) {
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": lirc register returned %d\n", result);
+ goto exit_buffer_free;
+ }
+
+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
+ if (!lirc_rpi_dev) {
+ result = -ENOMEM;
+ goto exit_driver_unregister;
+ }
+
+ result = platform_device_add(lirc_rpi_dev);
+ if (result)
+ goto exit_device_put;
+
+ return 0;
+
+ exit_device_put:
+ platform_device_put(lirc_rpi_dev);
+
+ exit_driver_unregister:
+ platform_driver_unregister(&lirc_rpi_driver);
+
+ exit_buffer_free:
+ lirc_buffer_free(&rbuf);
+
+ return result;
+}
+
+static void lirc_rpi_exit(void)
+{
+ if (!lirc_rpi_dev->dev.of_node)
+ platform_device_unregister(lirc_rpi_dev);
+ platform_driver_unregister(&lirc_rpi_driver);
+ lirc_buffer_free(&rbuf);
+}
+
+static int __init lirc_rpi_init_module(void)
+{
+ int result;
+
+ result = lirc_rpi_init();
+ if (result)
+ return result;
+
+ if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) {
+ result = -EINVAL;
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": invalid GPIO pin(s) specified!\n");
+ goto exit_rpi;
+ }
+
+ result = init_port();
+ if (result < 0)
+ goto exit_rpi;
+
+ driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
+ LIRC_CAN_SET_SEND_CARRIER |
+ LIRC_CAN_SEND_PULSE |
+ LIRC_CAN_REC_MODE2;
+
+ driver.dev = &lirc_rpi_dev->dev;
+ driver.minor = lirc_register_driver(&driver);
+
+ if (driver.minor < 0) {
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": device registration failed with %d\n", result);
+ result = -EIO;
+ goto exit_rpi;
+ }
+
+ printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
+
+ return 0;
+
+ exit_rpi:
+ lirc_rpi_exit();
+
+ return result;
+}
+
+static void __exit lirc_rpi_exit_module(void)
+{
+ lirc_unregister_driver(driver.minor);
+
+ gpio_free(gpio_out_pin);
+ gpio_free(gpio_in_pin);
+
+ lirc_rpi_exit();
+
+ printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
+}
+
+module_init(lirc_rpi_init_module);
+module_exit(lirc_rpi_exit_module);
+
+MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
+MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
+MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
+MODULE_LICENSE("GPL");
+
+module_param(gpio_out_pin, int, S_IRUGO);
+MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
+ " processor. (default 17");
+
+module_param(gpio_in_pin, int, S_IRUGO);
+MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
+ " (default 18");
+
+module_param(gpio_in_pull, int, S_IRUGO);
+MODULE_PARM_DESC(gpio_in_pull, "GPIO input pin pull configuration."
+ " (0 = off, 1 = up, 2 = down, default down)");
+
+module_param(sense, int, S_IRUGO);
+MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
+ " (0 = active high, 1 = active low )");
+
+module_param(softcarrier, bool, S_IRUGO);
+MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
+
+module_param(invert, bool, S_IRUGO);
+MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging messages");
--
1.8.3.2

View file

@ -0,0 +1,289 @@
From f8628f418651bcb52604f943c00c45d932ff3572 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:49:20 +0100
Subject: [PATCH 016/114] Add cpufreq driver
---
arch/arm/Kconfig | 1 +
drivers/cpufreq/Kconfig.arm | 8 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/bcm2835-cpufreq.c | 224 ++++++++++++++++++++++++++++++++++++++
4 files changed, 234 insertions(+)
create mode 100755 drivers/cpufreq/bcm2835-cpufreq.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4cedaf2..6283d7d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -390,6 +390,7 @@ config ARCH_BCM2708
select NEED_MACH_GPIO_H
select NEED_MACH_MEMORY_H
select CLKDEV_LOOKUP
+ select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARM_ERRATA_411920
select MACH_BCM2708
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 83a75dc..210394f 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -241,6 +241,14 @@ config ARM_SPEAR_CPUFREQ
help
This adds the CPUFreq driver support for SPEAr SOCs.
+config ARM_BCM2835_CPUFREQ
+ bool "BCM2835 Driver"
+ default y
+ help
+ This adds the CPUFreq driver for BCM2835
+
+ If in doubt, say N.
+
config ARM_TEGRA_CPUFREQ
bool "TEGRA CPUFreq support"
depends on ARCH_TEGRA
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 40c53dc..47d2922 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o
obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o
obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o
+obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o
obj-$(CONFIG_ARM_TEGRA_CPUFREQ) += tegra-cpufreq.o
obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c
new file mode 100755
index 0000000..447ca09
--- /dev/null
+++ b/drivers/cpufreq/bcm2835-cpufreq.c
@@ -0,0 +1,224 @@
+/*****************************************************************************
+* Copyright 2011 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*****************************************************************************
+* FILENAME: bcm2835-cpufreq.h
+* DESCRIPTION: This driver dynamically manages the CPU Frequency of the ARM
+* processor. Messages are sent to Videocore either setting or requesting the
+* frequency of the ARM in order to match an appropiate frequency to the current
+* usage of the processor. The policy which selects the frequency to use is
+* defined in the kernel .config file, but can be changed during runtime.
+*****************************************************************************/
+
+/* ---------- INCLUDES ---------- */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/cpufreq.h>
+#include <mach/vcio.h>
+
+/* ---------- DEFINES ---------- */
+/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */
+#define MODULE_NAME "bcm2835-cpufreq"
+
+#define VCMSG_ID_ARM_CLOCK 0x000000003 /* Clock/Voltage ID's */
+
+/* debug printk macros */
+#ifdef CPUFREQ_DEBUG_ENABLE
+#define print_debug(fmt,...) pr_debug("%s:%s:%d: "fmt, MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define print_debug(fmt,...)
+#endif
+#define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
+#define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__)
+
+/* tag part of the message */
+struct vc_msg_tag {
+ uint32_t tag_id; /* the message id */
+ uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */
+ uint32_t data_size; /* amount of data being sent or received */
+ uint32_t dev_id; /* the ID of the clock/voltage to get or set */
+ uint32_t val; /* the value (e.g. rate (in Hz)) to set */
+};
+
+/* message structure to be sent to videocore */
+struct vc_msg {
+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
+ struct vc_msg_tag tag; /* the tag structure above to make */
+ uint32_t end_tag; /* an end identifier, should be set to NULL */
+};
+
+/* ---------- GLOBALS ---------- */
+static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */
+
+static struct cpufreq_frequency_table bcm2835_freq_table[] = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, CPUFREQ_TABLE_END},
+};
+
+/*
+ ===============================================
+ clk_rate either gets or sets the clock rates.
+ ===============================================
+*/
+static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate)
+{
+ int s, actual_rate=0;
+ struct vc_msg msg;
+
+ /* wipe all previous message data */
+ memset(&msg, 0, sizeof msg);
+
+ msg.msg_size = sizeof msg;
+
+ msg.tag.tag_id = VCMSG_SET_CLOCK_RATE;
+ msg.tag.buffer_size = 8;
+ msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */
+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK;
+ msg.tag.val = arm_rate * 1000;
+
+ /* send the message */
+ s = bcm_mailbox_property(&msg, sizeof msg);
+
+ /* check if it was all ok and return the rate in KHz */
+ if (s == 0 && (msg.request_code & 0x80000000))
+ actual_rate = msg.tag.val/1000;
+
+ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate);
+ return actual_rate;
+}
+
+static uint32_t bcm2835_cpufreq_get_clock(int tag)
+{
+ int s;
+ int arm_rate = 0;
+ struct vc_msg msg;
+
+ /* wipe all previous message data */
+ memset(&msg, 0, sizeof msg);
+
+ msg.msg_size = sizeof msg;
+ msg.tag.tag_id = tag;
+ msg.tag.buffer_size = 8;
+ msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */
+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK;
+
+ /* send the message */
+ s = bcm_mailbox_property(&msg, sizeof msg);
+
+ /* check if it was all ok and return the rate in KHz */
+ if (s == 0 && (msg.request_code & 0x80000000))
+ arm_rate = msg.tag.val/1000;
+
+ print_debug("%s frequency = %d\n",
+ tag == VCMSG_GET_CLOCK_RATE ? "Current":
+ tag == VCMSG_GET_MIN_CLOCK ? "Min":
+ tag == VCMSG_GET_MAX_CLOCK ? "Max":
+ "Unexpected", arm_rate);
+
+ return arm_rate;
+}
+
+/*
+ ====================================================
+ Module Initialisation registers the cpufreq driver
+ ====================================================
+*/
+static int __init bcm2835_cpufreq_module_init(void)
+{
+ print_debug("IN\n");
+ return cpufreq_register_driver(&bcm2835_cpufreq_driver);
+}
+
+/*
+ =============
+ Module exit
+ =============
+*/
+static void __exit bcm2835_cpufreq_module_exit(void)
+{
+ print_debug("IN\n");
+ cpufreq_unregister_driver(&bcm2835_cpufreq_driver);
+ return;
+}
+
+/*
+ ==============================================================
+ Initialisation function sets up the CPU policy for first use
+ ==============================================================
+*/
+static int bcm2835_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+ /* measured value of how long it takes to change frequency */
+ const unsigned int transition_latency = 355000; /* ns */
+
+ /* now find out what the maximum and minimum frequencies are */
+ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK);
+ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK);
+
+ print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency);
+ return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency);
+}
+
+/*
+ =====================================================================
+ Target index function chooses the requested frequency from the table
+ =====================================================================
+*/
+
+static int bcm2835_cpufreq_driver_target_index(struct cpufreq_policy *policy, unsigned int state)
+{
+ unsigned int target_freq = bcm2835_freq_table[state].frequency;
+ unsigned int cur = bcm2835_cpufreq_set_clock(policy->cur, target_freq);
+
+ if (!cur)
+ {
+ print_err("Error occurred setting a new frequency (%d)\n", target_freq);
+ return -EINVAL;
+ }
+ print_debug("%s: %i: freq %d->%d\n", policy->governor->name, state, policy->cur, cur);
+ return 0;
+}
+
+/*
+ ======================================================
+ Get function returns the current frequency from table
+ ======================================================
+*/
+
+static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu)
+{
+ unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE);
+ print_debug("%d: freq=%d\n", cpu, actual_rate);
+ return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency;
+}
+
+/* the CPUFreq driver */
+static struct cpufreq_driver bcm2835_cpufreq_driver = {
+ .name = "BCM2835 CPUFreq",
+ .init = bcm2835_cpufreq_driver_init,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = bcm2835_cpufreq_driver_target_index,
+ .get = bcm2835_cpufreq_driver_get,
+ .attr = cpufreq_generic_attr,
+};
+
+MODULE_AUTHOR("Dorian Peake and Dom Cobley");
+MODULE_DESCRIPTION("CPU frequency driver for BCM2835 chip");
+MODULE_LICENSE("GPL");
+
+module_init(bcm2835_cpufreq_module_init);
+module_exit(bcm2835_cpufreq_module_exit);
--
1.8.3.2

View file

@ -0,0 +1,527 @@
From de9bdcff7ec73589cb314a1569ce5aba5fe09146 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 19:24:24 +0000
Subject: [PATCH 017/114] Added hwmon/thermal driver for reporting core
temperature. Thanks Dorian
---
arch/arm/mach-bcm2708/bcm2708.c | 11 ++
drivers/hwmon/Kconfig | 10 ++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/bcm2835-hwmon.c | 219 ++++++++++++++++++++++++++++++++++++++
drivers/thermal/Kconfig | 6 ++
drivers/thermal/Makefile | 1 +
drivers/thermal/bcm2835-thermal.c | 184 ++++++++++++++++++++++++++++++++
7 files changed, 432 insertions(+)
create mode 100644 drivers/hwmon/bcm2835-hwmon.c
create mode 100644 drivers/thermal/bcm2835-thermal.c
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index f3dccae..af57d11 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -455,6 +455,14 @@ static struct platform_device bcm2708_alsa_devices[] = {
},
};
+static struct platform_device bcm2835_hwmon_device = {
+ .name = "bcm2835_hwmon",
+};
+
+static struct platform_device bcm2835_thermal_device = {
+ .name = "bcm2835_thermal",
+};
+
int __init bcm_register_device(struct platform_device *pdev)
{
int ret;
@@ -563,6 +571,9 @@ void __init bcm2708_init(void)
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
bcm_register_device(&bcm2708_alsa_devices[i]);
+ bcm_register_device(&bcm2835_hwmon_device);
+ bcm_register_device(&bcm2835_thermal_device);
+
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 5286d7c..d52e192 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1680,6 +1680,16 @@ config SENSORS_ULTRA45
This driver provides support for the Ultra45 workstation environmental
sensors.
+config SENSORS_BCM2835
+ depends on THERMAL_BCM2835=n
+ tristate "Broadcom BCM2835 HWMON Driver"
+ help
+ If you say yes here you get support for the hardware
+ monitoring features of the BCM2835 Chip
+
+ This driver can also be built as a module. If so, the module
+ will be called bcm2835-hwmon.
+
if ACPI
comment "ACPI drivers"
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c90a761..15aaecf 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -153,6 +153,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
obj-$(CONFIG_SENSORS_GSC) += gsc.o
+obj-$(CONFIG_SENSORS_BCM2835) += bcm2835-hwmon.o
obj-$(CONFIG_PMBUS) += pmbus/
diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c
new file mode 100644
index 0000000..5bbed45
--- /dev/null
+++ b/drivers/hwmon/bcm2835-hwmon.c
@@ -0,0 +1,219 @@
+/*****************************************************************************
+* Copyright 2011 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <mach/vcio.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#define MODULE_NAME "bcm2835_hwmon"
+
+/*#define HWMON_DEBUG_ENABLE*/
+
+#ifdef HWMON_DEBUG_ENABLE
+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define print_debug(fmt,...)
+#endif
+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
+#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__)
+
+#define VC_TAG_GET_TEMP 0x00030006
+#define VC_TAG_GET_MAX_TEMP 0x0003000A
+
+/* --- STRUCTS --- */
+struct bcm2835_hwmon_data {
+ struct device *hwmon_dev;
+};
+
+/* tag part of the message */
+struct vc_msg_tag {
+ uint32_t tag_id; /* the tag ID for the temperature */
+ uint32_t buffer_size; /* size of the buffer (should be 8) */
+ uint32_t request_code; /* identifies message as a request (should be 0) */
+ uint32_t id; /* extra ID field (should be 0) */
+ uint32_t val; /* returned value of the temperature */
+};
+
+/* message structure to be sent to videocore */
+struct vc_msg {
+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
+ struct vc_msg_tag tag; /* the tag structure above to make */
+ uint32_t end_tag; /* an end identifier, should be set to NULL */
+};
+
+typedef enum {
+ TEMP,
+ MAX_TEMP,
+} temp_type;
+
+/* --- PROTOTYPES --- */
+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf);
+
+/* --- GLOBALS --- */
+
+static struct bcm2835_hwmon_data *bcm2835_data;
+static struct platform_driver bcm2835_hwmon_driver;
+
+static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0);
+static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP);
+static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP);
+
+static struct attribute* bcm2835_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group bcm2835_attr_group = {
+ .attrs = bcm2835_attributes,
+};
+
+/* --- FUNCTIONS --- */
+
+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf,"bcm2835_hwmon\n");
+}
+
+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vc_msg msg;
+ int result;
+ uint temp = 0;
+ int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index;
+
+ print_debug("IN");
+
+ /* wipe all previous message data */
+ memset(&msg, 0, sizeof msg);
+
+ /* determine the message type */
+ if(index == TEMP)
+ msg.tag.tag_id = VC_TAG_GET_TEMP;
+ else if (index == MAX_TEMP)
+ msg.tag.tag_id = VC_TAG_GET_MAX_TEMP;
+ else
+ {
+ print_debug("Unknown temperature message!");
+ return -EINVAL;
+ }
+
+ msg.msg_size = sizeof msg;
+ msg.tag.buffer_size = 8;
+
+ /* send the message */
+ result = bcm_mailbox_property(&msg, sizeof msg);
+
+ /* check if it was all ok and return the rate in milli degrees C */
+ if (result == 0 && (msg.request_code & 0x80000000))
+ temp = (uint)msg.tag.val;
+ #ifdef HWMON_DEBUG_ENABLE
+ else
+ print_debug("Failed to get temperature!");
+ #endif
+ print_debug("Got temperature as %u",temp);
+ print_debug("OUT");
+ return sprintf(buf, "%u\n", temp);
+}
+
+
+static int bcm2835_hwmon_probe(struct platform_device *pdev)
+{
+ int err;
+
+ print_debug("IN");
+ print_debug("HWMON Driver has been probed!");
+
+ /* check that the device isn't null!*/
+ if(pdev == NULL)
+ {
+ print_debug("Platform device is empty!");
+ return -ENODEV;
+ }
+
+ /* allocate memory for neccessary data */
+ bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL);
+ if(!bcm2835_data)
+ {
+ print_debug("Unable to allocate memory for hwmon data!");
+ err = -ENOMEM;
+ goto kzalloc_error;
+ }
+
+ /* create the sysfs files */
+ if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group))
+ {
+ print_debug("Unable to create sysfs files!");
+ err = -EFAULT;
+ goto sysfs_error;
+ }
+
+ /* register the hwmon device */
+ bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(bcm2835_data->hwmon_dev))
+ {
+ err = PTR_ERR(bcm2835_data->hwmon_dev);
+ goto hwmon_error;
+ }
+ print_debug("OUT");
+ return 0;
+
+ /* error goto's */
+ hwmon_error:
+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group);
+
+ sysfs_error:
+ kfree(bcm2835_data);
+
+ kzalloc_error:
+
+ return err;
+
+}
+
+static int bcm2835_hwmon_remove(struct platform_device *pdev)
+{
+ print_debug("IN");
+ hwmon_device_unregister(bcm2835_data->hwmon_dev);
+
+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group);
+ print_debug("OUT");
+ return 0;
+}
+
+/* Hwmon Driver */
+static struct platform_driver bcm2835_hwmon_driver = {
+ .probe = bcm2835_hwmon_probe,
+ .remove = bcm2835_hwmon_remove,
+ .driver = {
+ .name = "bcm2835_hwmon",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dorian Peake");
+MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip");
+
+module_platform_driver(bcm2835_hwmon_driver);
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index f554d25..fecc621 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -206,6 +206,12 @@ config INTEL_POWERCLAMP
enforce idle time which results in more package C-state residency. The
user interface is exposed via generic thermal framework.
+config THERMAL_BCM2835
+ tristate "BCM2835 Thermal Driver"
+ help
+ This will enable temperature monitoring for the Broadcom BCM2835
+ chip. If built as a module, it will be called 'bcm2835-thermal'.
+
config X86_PKG_TEMP_THERMAL
tristate "X86 package temperature thermal driver"
depends on X86_THERMAL_VECTOR
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 39c4fe8..30a4741 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
+obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o
obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c
new file mode 100644
index 0000000..85fceb5
--- /dev/null
+++ b/drivers/thermal/bcm2835-thermal.c
@@ -0,0 +1,184 @@
+/*****************************************************************************
+* Copyright 2011 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <mach/vcio.h>
+#include <linux/thermal.h>
+
+
+/* --- DEFINITIONS --- */
+#define MODULE_NAME "bcm2835_thermal"
+
+/*#define THERMAL_DEBUG_ENABLE*/
+
+#ifdef THERMAL_DEBUG_ENABLE
+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define print_debug(fmt,...)
+#endif
+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
+
+#define VC_TAG_GET_TEMP 0x00030006
+#define VC_TAG_GET_MAX_TEMP 0x0003000A
+
+typedef enum {
+ TEMP,
+ MAX_TEMP,
+} temp_type;
+
+/* --- STRUCTS --- */
+/* tag part of the message */
+struct vc_msg_tag {
+ uint32_t tag_id; /* the tag ID for the temperature */
+ uint32_t buffer_size; /* size of the buffer (should be 8) */
+ uint32_t request_code; /* identifies message as a request (should be 0) */
+ uint32_t id; /* extra ID field (should be 0) */
+ uint32_t val; /* returned value of the temperature */
+};
+
+/* message structure to be sent to videocore */
+struct vc_msg {
+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
+ struct vc_msg_tag tag; /* the tag structure above to make */
+ uint32_t end_tag; /* an end identifier, should be set to NULL */
+};
+
+struct bcm2835_thermal_data {
+ struct thermal_zone_device *thermal_dev;
+ struct vc_msg msg;
+};
+
+/* --- GLOBALS --- */
+static struct bcm2835_thermal_data bcm2835_data;
+
+/* Thermal Device Operations */
+static struct thermal_zone_device_ops ops;
+
+/* --- FUNCTIONS --- */
+
+static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id)
+{
+ int result = -1, retry = 3;
+ print_debug("IN");
+
+ *temp = 0;
+ while (result != 0 && retry-- > 0) {
+ /* wipe all previous message data */
+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
+
+ /* prepare message */
+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
+ bcm2835_data.msg.tag.buffer_size = 8;
+ bcm2835_data.msg.tag.tag_id = tag_id;
+
+ /* send the message */
+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
+ print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code);
+ if (!(bcm2835_data.msg.request_code & 0x80000000))
+ result = -1;
+ }
+
+ /* check if it was all ok and return the rate in milli degrees C */
+ if (result == 0)
+ *temp = (uint)bcm2835_data.msg.tag.val;
+ else
+ print_err("Failed to get temperature! (%x:%d)\n", tag_id, result);
+ print_debug("OUT");
+ return result;
+}
+
+static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp)
+{
+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP);
+}
+
+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp)
+{
+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP);
+}
+
+static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type)
+{
+ *trip_type = THERMAL_TRIP_HOT;
+ return 0;
+}
+
+
+static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode)
+{
+ *dev_mode = THERMAL_DEVICE_ENABLED;
+ return 0;
+}
+
+
+static int bcm2835_thermal_probe(struct platform_device *pdev)
+{
+ print_debug("IN");
+ print_debug("THERMAL Driver has been probed!");
+
+ /* check that the device isn't null!*/
+ if(pdev == NULL)
+ {
+ print_debug("Platform device is empty!");
+ return -ENODEV;
+ }
+
+ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0)))
+ {
+ print_debug("Unable to register the thermal device!");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+
+static int bcm2835_thermal_remove(struct platform_device *pdev)
+{
+ print_debug("IN");
+
+ thermal_zone_device_unregister(bcm2835_data.thermal_dev);
+
+ print_debug("OUT");
+
+ return 0;
+}
+
+static struct thermal_zone_device_ops ops = {
+ .get_temp = bcm2835_get_temp,
+ .get_trip_temp = bcm2835_get_max_temp,
+ .get_trip_type = bcm2835_get_trip_type,
+ .get_mode = bcm2835_get_mode,
+};
+
+/* Thermal Driver */
+static struct platform_driver bcm2835_thermal_driver = {
+ .probe = bcm2835_thermal_probe,
+ .remove = bcm2835_thermal_remove,
+ .driver = {
+ .name = "bcm2835_thermal",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dorian Peake");
+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
+
+module_platform_driver(bcm2835_thermal_driver);
--
1.8.3.2

View file

@ -0,0 +1,96 @@
From c732e3a3218671786b589835260995bc24715248 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 17:26:38 +0000
Subject: [PATCH 018/114] Allow mac address to be set in smsc95xx
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index d07bf4c..5ae60ab 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -59,6 +59,7 @@
#define SUSPEND_SUSPEND3 (0x08)
#define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \
SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3)
+#define MAC_ADDR_LEN (6)
struct smsc95xx_priv {
u32 mac_cr;
@@ -74,6 +75,10 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+static char *macaddr = ":";
+module_param(macaddr, charp, 0);
+MODULE_PARM_DESC(macaddr, "MAC address");
+
static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data, int in_pm)
{
@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}
+/* Check the macaddr module parameter for a MAC address */
+static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac)
+{
+ int i, j, got_num, num;
+ u8 mtbl[MAC_ADDR_LEN];
+
+ if (macaddr[0] == ':')
+ return 0;
+
+ i = 0;
+ j = 0;
+ num = 0;
+ got_num = 0;
+ while (j < MAC_ADDR_LEN) {
+ if (macaddr[i] && macaddr[i] != ':') {
+ got_num++;
+ if ('0' <= macaddr[i] && macaddr[i] <= '9')
+ num = num * 16 + macaddr[i] - '0';
+ else if ('A' <= macaddr[i] && macaddr[i] <= 'F')
+ num = num * 16 + 10 + macaddr[i] - 'A';
+ else if ('a' <= macaddr[i] && macaddr[i] <= 'f')
+ num = num * 16 + 10 + macaddr[i] - 'a';
+ else
+ break;
+ i++;
+ } else if (got_num == 2) {
+ mtbl[j++] = (u8) num;
+ num = 0;
+ got_num = 0;
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ if (j == MAC_ADDR_LEN) {
+ netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2],
+ mtbl[3], mtbl[4], mtbl[5]);
+ for (i = 0; i < MAC_ADDR_LEN; i++)
+ dev_mac[i] = mtbl[i];
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
static void smsc95xx_init_mac_address(struct usbnet *dev)
{
+ /* Check module parameters */
+ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr))
+ return;
+
/* try reading mac address from EEPROM */
if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
dev->net->dev_addr) == 0) {
--
1.8.3.2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,77 @@
From 0262abfaac71799e3688285f1f30bead42b8ff7e Mon Sep 17 00:00:00 2001
From: cbeytas <cbeytas@shaw.ca>
Date: Mon, 24 Jun 2013 00:05:40 -0400
Subject: [PATCH 020/114] Perform I2C combined transactions when possible
Perform I2C combined transactions whenever possible, within the
restrictions of the Broadcomm Serial Controller.
Disable DONE interrupt during TA poll
Prevent interrupt from being triggered if poll is missed and transfer
starts and finishes.
i2c: Make combined transactions optional and disabled by default
---
drivers/i2c/busses/i2c-bcm2708.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c
index 09203c0..7d385a3 100644
--- a/drivers/i2c/busses/i2c-bcm2708.c
+++ b/drivers/i2c/busses/i2c-bcm2708.c
@@ -74,6 +74,9 @@ static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(baudrate, "The I2C baudrate");
+static bool combined = false;
+module_param(combined, bool, 0644);
+MODULE_PARM_DESC(combined, "Use combined transactions");
struct bcm2708_i2c {
struct i2c_adapter adapter;
@@ -150,7 +153,7 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
{
unsigned long bus_hz;
- u32 cdiv;
+ u32 cdiv, s;
u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
bus_hz = clk_get_rate(bi->clk);
@@ -166,6 +169,32 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
bcm2708_wr(bi, BSC_DIV, cdiv);
bcm2708_wr(bi, BSC_A, bi->msg->addr);
bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
+ if (combined)
+ {
+ /* Do the next two messages meet combined transaction criteria?
+ - Current message is a write, next message is a read
+ - Both messages to same slave address
+ - Write message can fit inside FIFO (16 bytes or less) */
+ if ( (bi->nmsgs > 1) &&
+ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
+ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
+ /* Fill FIFO with entire write message (16 byte FIFO) */
+ while (bi->pos < bi->msg->len)
+ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
+ /* Start write transfer (no interrupts, don't clear FIFO) */
+ bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
+ /* poll for transfer start bit (should only take 1-20 polls) */
+ do {
+ s = bcm2708_rd(bi, BSC_S);
+ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)));
+ /* Send next read message before the write transfer finishes. */
+ bi->nmsgs--;
+ bi->msg++;
+ bi->pos = 0;
+ bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
+ c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
+ }
+ }
bcm2708_wr(bi, BSC_C, c);
}
--
1.8.3.2

View file

@ -0,0 +1,277 @@
From bd7d1508a83c544f2d52f668ebabe55c2ea207c5 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 May 2013 11:46:50 +0100
Subject: [PATCH 021/114] enabling the realtime clock 1-wire chip DS1307 and
1-wire on GPIO4 (as a module)
1-wire: Add support for configuring pin for w1-gpio kernel module
See: https://github.com/raspberrypi/linux/pull/457
Add bitbanging pullups, use them for w1-gpio
Allows parasite power to work, uses module option pullup=1
bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter
Signed-off-by: Alex J Lennon <ajlennon@dynamicdevices.co.uk>
w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set
Signed-off-by: Alex J Lennon <ajlennon@dynamicdevices.co.uk>
---
arch/arm/mach-bcm2708/bcm2708.c | 29 ++++++++++++++++++++++
drivers/w1/masters/w1-gpio.c | 55 +++++++++++++++++++++++++++++++++++++----
drivers/w1/w1.h | 6 +++++
drivers/w1/w1_int.c | 14 +++++++++++
drivers/w1/w1_io.c | 18 +++++++++++---
5 files changed, 114 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 82f56fb..7dd89a7f 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -32,6 +32,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
+#include <linux/w1-gpio.h>
#include <linux/version.h>
#include <linux/clkdev.h>
@@ -76,12 +77,19 @@
*/
#define DMA_MASK_BITS_COMMON 32
+// use GPIO 4 for the one-wire GPIO pin, if enabled
+#define W1_GPIO 4
+// ensure one-wire GPIO pullup is disabled by default
+#define W1_PULLUP -1
+
/* command line parameters */
static unsigned boardrev, serial;
static unsigned uart_clock;
static unsigned disk_led_gpio = 16;
static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
+static unsigned w1_gpio_pin = W1_GPIO;
+static unsigned w1_gpio_pullup = W1_PULLUP;
static void __init bcm2708_init_led(void);
@@ -258,6 +266,20 @@ static struct platform_device bcm2708_dmaman_device = {
.num_resources = ARRAY_SIZE(bcm2708_dmaman_resources),
};
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+ .pin = W1_GPIO,
+ .ext_pullup_enable_pin = W1_PULLUP,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device = {
+ .name = "w1-gpio",
+ .id = -1,
+ .dev.platform_data = &w1_gpio_pdata,
+};
+#endif
+
static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
static struct platform_device bcm2708_fb_device = {
@@ -652,6 +674,11 @@ void __init bcm2708_init(void)
#ifdef CONFIG_BCM2708_GPIO
bcm_register_device(&bcm2708_gpio_device);
#endif
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+ w1_gpio_pdata.pin = w1_gpio_pin;
+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
+ platform_device_register(&w1_device);
+#endif
bcm_register_device(&bcm2708_systemtimer_device);
bcm_register_device(&bcm2708_fb_device);
bcm_register_device(&bcm2708_usb_device);
@@ -853,3 +880,5 @@ module_param(uart_clock, uint, 0644);
module_param(disk_led_gpio, uint, 0644);
module_param(disk_led_active_low, uint, 0644);
module_param(reboot_part, uint, 0644);
+module_param(w1_gpio_pin, uint, 0644);
+module_param(w1_gpio_pullup, uint, 0644);
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 1d111e5..61be2cd 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -23,6 +23,15 @@
#include "../w1.h"
#include "../w1_int.h"
+static int w1_gpio_pullup = -1;
+static int w1_gpio_pullup_orig = -1;
+module_param_named(pullup, w1_gpio_pullup, int, 0);
+MODULE_PARM_DESC(pullup, "GPIO pin pullup number");
+static int w1_gpio_pin = -1;
+static int w1_gpio_pin_orig = -1;
+module_param_named(gpiopin, w1_gpio_pin, int, 0);
+MODULE_PARM_DESC(gpiopin, "GPIO pin number");
+
static u8 w1_gpio_set_pullup(void *data, int delay)
{
struct w1_gpio_platform_data *pdata = data;
@@ -67,6 +76,16 @@ static u8 w1_gpio_read_bit(void *data)
return gpio_get_value(pdata->pin) ? 1 : 0;
}
+static void w1_gpio_bitbang_pullup(void *data, u8 on)
+{
+ struct w1_gpio_platform_data *pdata = data;
+
+ if (on)
+ gpio_direction_output(pdata->pin, 1);
+ else
+ gpio_direction_input(pdata->pin);
+}
+
#if defined(CONFIG_OF)
static struct of_device_id w1_gpio_dt_ids[] = {
{ .compatible = "w1-gpio" },
@@ -113,13 +132,15 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
static int w1_gpio_probe(struct platform_device *pdev)
{
struct w1_bus_master *master;
- struct w1_gpio_platform_data *pdata;
+ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
int err;
- if (of_have_populated_dt()) {
- err = w1_gpio_probe_dt(pdev);
- if (err < 0)
- return err;
+ if(pdata == NULL) {
+ if (of_have_populated_dt()) {
+ err = w1_gpio_probe_dt(pdev);
+ if (err < 0)
+ return err;
+ }
}
pdata = dev_get_platdata(&pdev->dev);
@@ -136,6 +157,19 @@ static int w1_gpio_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ w1_gpio_pin_orig = pdata->pin;
+ w1_gpio_pullup_orig = pdata->ext_pullup_enable_pin;
+
+ if(gpio_is_valid(w1_gpio_pin)) {
+ pdata->pin = w1_gpio_pin;
+ pdata->ext_pullup_enable_pin = -1;
+ }
+ if(gpio_is_valid(w1_gpio_pullup)) {
+ pdata->ext_pullup_enable_pin = w1_gpio_pullup;
+ }
+
+ dev_info(&pdev->dev, "gpio pin %d, gpio pullup pin %d\n", pdata->pin, pdata->ext_pullup_enable_pin);
+
err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");
if (err) {
dev_err(&pdev->dev, "gpio_request (pin) failed\n");
@@ -165,6 +199,14 @@ static int w1_gpio_probe(struct platform_device *pdev)
master->set_pullup = w1_gpio_set_pullup;
}
+ if (gpio_is_valid(w1_gpio_pullup)) {
+ if (pdata->is_open_drain)
+ printk(KERN_ERR "w1-gpio 'pullup' option "
+ "doesn't work with open drain GPIO\n");
+ else
+ master->bitbang_pullup = w1_gpio_bitbang_pullup;
+ }
+
err = w1_add_master_device(master);
if (err) {
dev_err(&pdev->dev, "w1_add_master device failed\n");
@@ -195,6 +237,9 @@ static int w1_gpio_remove(struct platform_device *pdev)
w1_remove_master_device(master);
+ pdata->pin = w1_gpio_pin_orig;
+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_orig;
+
return 0;
}
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index 56a49ba..881d728 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -171,6 +171,12 @@ struct w1_bus_master
u8 (*set_pullup)(void *, int);
+ /**
+ * Turns the pullup on/off in bitbanging mode, takes an on/off argument.
+ * @return -1=Error, 0=completed
+ */
+ void (*bitbang_pullup) (void *, u8);
+
void (*search)(void *, struct w1_master *,
u8, w1_slave_found_callback);
};
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 47249a3..a4b4a8d 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -123,6 +123,20 @@ int w1_add_master_device(struct w1_bus_master *master)
return(-EINVAL);
}
+ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup
+ * and takes care of timing itself */
+ if (!master->write_byte && !master->touch_bit && master->set_pullup) {
+ printk(KERN_ERR "w1_add_master_device: set_pullup requires "
+ "write_byte or touch_bit, disabling\n");
+ master->set_pullup = NULL;
+ }
+
+ if (master->set_pullup && master->bitbang_pullup) {
+ printk(KERN_ERR "w1_add_master_device: set_pullup should not "
+ "be set when bitbang_pullup is used, disabling\n");
+ master->set_pullup = NULL;
+ }
+
/* Lock until the device is added (or not) to w1_masters. */
mutex_lock(&w1_mlock);
/* Search for the first available id (starting at 1). */
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 2820924..fd0550f 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -134,10 +134,22 @@ static void w1_pre_write(struct w1_master *dev)
static void w1_post_write(struct w1_master *dev)
{
if (dev->pullup_duration) {
- if (dev->enable_pullup && dev->bus_master->set_pullup)
- dev->bus_master->set_pullup(dev->bus_master->data, 0);
- else
+ if (dev->enable_pullup) {
+ if (dev->bus_master->set_pullup) {
+ dev->bus_master->set_pullup(dev->
+ bus_master->data,
+ 0);
+ } else if (dev->bus_master->bitbang_pullup) {
+ dev->bus_master->
+ bitbang_pullup(dev->bus_master->data, 1);
+ msleep(dev->pullup_duration);
+ dev->bus_master->
+ bitbang_pullup(dev->bus_master->data, 0);
+ }
+ } else {
msleep(dev->pullup_duration);
+ }
+
dev->pullup_duration = 0;
}
}
--
1.8.3.2

View file

@ -0,0 +1,27 @@
From 007dc7d958e34055cbd23889784e9418e221254f Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:54:08 +0100
Subject: [PATCH 022/114] Added Device IDs for August DVB-T 205
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 27b1e03..a2997b7 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1531,6 +1531,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
&rtl2832u_props, "Compro VideoMate U620F", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
&rtl2832u_props, "MaxMedia HU394-T", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, 0xb803 /*USB_PID_AUGUST_DVBT205*/,
+ &rtl2832u_props, "August DVB-T 205", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803 /*USB_PID_AUGUST_DVBT205*/,
+ &rtl2832u_props, "August DVB-T 205", NULL) },
{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03,
&rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) },
{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
--
1.8.3.2

View file

@ -0,0 +1,939 @@
From 13c96adb3a82e72a05a12ba833743b49d2e00ed9 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 12 Apr 2013 23:58:47 +0100
Subject: [PATCH 023/114] config: add missing options from 3.6.y kernel
---
arch/arm/configs/bcmrpi_defconfig | 658 ++++++++++++++++++++++++++++++++++++--
1 file changed, 636 insertions(+), 22 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 6d2eae1..e2da9da 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -1,3 +1,5 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_PHYS_OFFSET=0
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -7,6 +9,10 @@ CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUP_FREEZER=y
@@ -16,28 +22,41 @@ CONFIG_RESOURCE_COUNTERS=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAC_PARTITION=y
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_ARCH_BCM2708=y
+CONFIG_PREEMPT=y
CONFIG_AEABI=y
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_CMA=y
+CONFIG_UACCESS_WITH_MEMCPY=y
CONFIG_SECCOMP=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_BINFMT_MISC=m
@@ -48,19 +67,272 @@ CONFIG_XFRM_USER=y
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=m
+CONFIG_INET_DIAG=m
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_ATM=m
+CONFIG_L2TP=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_ATALK=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_EMATCH_IPSET=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_BATMAN_ADV=m
+CONFIG_OPENVSWITCH=m
CONFIG_NET_PKTGEN=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
CONFIG_IRDA=m
CONFIG_IRLAN=m
+CONFIG_IRNET=m
CONFIG_IRCOMM=m
CONFIG_IRDA_ULTRA=y
CONFIG_IRDA_CACHE_LAST_LSAP=y
@@ -87,45 +359,87 @@ CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_ATH3K=m
-CONFIG_CFG80211=m
+CONFIG_BT_WILINK=m
+CONFIG_CFG80211_WEXT=y
CONFIG_MAC80211=m
CONFIG_MAC80211_MESH=y
CONFIG_WIMAX=m
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
CONFIG_NET_9P=m
CONFIG_NFC=m
CONFIG_NFC_PN533=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=5
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_CDROM_PKTCDVD=m
+CONFIG_EEPROM_AT24=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
-# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_ISCSI_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_DELAY=m
CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
CONFIG_NETCONSOLE=m
CONFIG_TUN=m
+CONFIG_VETH=m
CONFIG_MDIO_BITBANG=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOATM=m
+CONFIG_PPPOE=m
+CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_AX88179_178A=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_CDC_NCM=m
+CONFIG_USB_NET_HUAWEI_CDC_NCM=m
+CONFIG_USB_NET_CDC_MBIM=m
CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9700=m
+CONFIG_USB_NET_SR9800=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_NET_GL620A=m
@@ -135,10 +449,13 @@ CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
-# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_USB_NET_ZAURUS=m
CONFIG_USB_NET_CX82310_ETH=m
CONFIG_USB_NET_KALMIA=m
+CONFIG_USB_NET_QMI_WWAN=m
+CONFIG_USB_HSO=m
CONFIG_USB_NET_INT51X1=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
@@ -150,7 +467,15 @@ CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_RTL8187=m
CONFIG_MAC80211_HWSIM=m
+CONFIG_ATH_CARDS=m
+CONFIG_ATH9K=m
+CONFIG_ATH9K_HTC=m
+CONFIG_CARL9170=m
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_USB=m
+CONFIG_AR5523=m
CONFIG_B43=m
+# CONFIG_B43_PHY_N is not set
CONFIG_B43LEGACY=m
CONFIG_HOSTAP=m
CONFIG_LIBERTAS=m
@@ -162,7 +487,10 @@ CONFIG_RT2X00=m
CONFIG_RT2500USB=m
CONFIG_RT73USB=m
CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT3573=y
CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
CONFIG_RTL8192CU=m
CONFIG_ZD1211RW=m
CONFIG_MWIFIEX=m
@@ -174,6 +502,13 @@ CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_AD714X=m
CONFIG_INPUT_ATI_REMOTE2=m
@@ -189,22 +524,207 @@ CONFIG_SERIO_RAW=m
CONFIG_GAMEPORT=m
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
+CONFIG_TTY_PRINTK=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_BCM2708=m
CONFIG_RAW_DRIVER=y
+CONFIG_BRCM_CHAR_DRIVERS=y
+CONFIG_BCM_VC_CMA=y
+CONFIG_BCM_VC_SM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_BCM2708=m
CONFIG_SPI=y
CONFIG_SPI_BCM2708=m
-CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_SPIDEV=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_ARIZONA=m
+CONFIG_W1=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+CONFIG_W1_MASTER_DS1WM=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2408=m
+CONFIG_W1_SLAVE_DS2413=m
+CONFIG_W1_SLAVE_DS2406=m
+CONFIG_W1_SLAVE_DS2423=m
+CONFIG_W1_SLAVE_DS2431=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2760=m
+CONFIG_W1_SLAVE_DS2780=m
+CONFIG_W1_SLAVE_DS2781=m
+CONFIG_W1_SLAVE_DS28E04=m
+CONFIG_W1_SLAVE_BQ27000=m
+CONFIG_BATTERY_DS2760=m
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_BCM2835=y
CONFIG_WATCHDOG=y
+CONFIG_BCM2708_WDT=m
+CONFIG_UCB1400_CORE=m
+CONFIG_MFD_ARIZONA_I2C=m
+CONFIG_MFD_ARIZONA_SPI=m
+CONFIG_MFD_WM5102=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+CONFIG_MEDIA_RC_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_LIRC=m
+CONFIG_RC_DEVICES=y
+CONFIG_RC_ATI_REMOTE=m
+CONFIG_IR_IMON=m
+CONFIG_IR_MCEUSB=m
+CONFIG_IR_REDRAT3=m
+CONFIG_IR_STREAMZAP=m
+CONFIG_IR_IGUANA=m
+CONFIG_IR_TTUSBIR=m
+CONFIG_RC_LOOPBACK=m
+CONFIG_IR_GPIO_CIR=m
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
+CONFIG_USB_GL860=m
+CONFIG_USB_GSPCA_BENQ=m
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_CPIA1=m
+CONFIG_USB_GSPCA_DTCS033=m
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
+CONFIG_USB_GSPCA_JEILINJ=m
+CONFIG_USB_GSPCA_JL2005BCD=m
+CONFIG_USB_GSPCA_KINECT=m
+CONFIG_USB_GSPCA_KONICA=m
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_NW80X=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_OV534_9=m
+CONFIG_USB_GSPCA_PAC207=m
+CONFIG_USB_GSPCA_PAC7302=m
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SE401=m
+CONFIG_USB_GSPCA_SN9C2028=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SPCA1528=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_SQ930X=m
+CONFIG_USB_GSPCA_STK014=m
+CONFIG_USB_GSPCA_STK1135=m
+CONFIG_USB_GSPCA_STV0680=m
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TOPRO=m
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_VICAM=m
+CONFIG_USB_GSPCA_XIRLINK_CIT=m
+CONFIG_USB_GSPCA_ZC3XX=m
+CONFIG_USB_PWC=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_USB_ZR364XX=m
+CONFIG_USB_STKWEBCAM=m
+CONFIG_USB_S2255=m
+CONFIG_VIDEO_USBTV=m
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_TLG2300=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_STK1160_COMMON=m
+CONFIG_VIDEO_STK1160_AC97=y
+CONFIG_VIDEO_GO7007=m
+CONFIG_VIDEO_GO7007_USB=m
+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m
+CONFIG_VIDEO_AU0828=m
+CONFIG_VIDEO_AU0828_RC=y
+CONFIG_VIDEO_CX231XX=m
+CONFIG_VIDEO_CX231XX_ALSA=m
+CONFIG_VIDEO_CX231XX_DVB=m
+CONFIG_VIDEO_TM6000=m
+CONFIG_VIDEO_TM6000_ALSA=m
+CONFIG_VIDEO_TM6000_DVB=m
+CONFIG_DVB_USB=m
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+CONFIG_DVB_USB_PCTV452E=m
+CONFIG_DVB_USB_DW2102=m
+CONFIG_DVB_USB_CINERGY_T2=m
+CONFIG_DVB_USB_DTV5100=m
+CONFIG_DVB_USB_FRIIO=m
+CONFIG_DVB_USB_AZ6027=m
+CONFIG_DVB_USB_TECHNISAT_USB2=m
+CONFIG_DVB_USB_V2=m
+CONFIG_DVB_USB_AF9015=m
+CONFIG_DVB_USB_AF9035=m
+CONFIG_DVB_USB_ANYSEE=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_AZ6007=m
+CONFIG_DVB_USB_CE6230=m
+CONFIG_DVB_USB_EC168=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_LME2510=m
+CONFIG_DVB_USB_MXL111SF=m
+CONFIG_DVB_USB_RTL28XXU=m
+CONFIG_SMS_USB_DRV=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+CONFIG_DVB_AS102=m
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_EM28XX_ALSA=m
+CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_RADIO_SI470X=y
+CONFIG_USB_SI470X=m
+CONFIG_I2C_SI470X=m
+CONFIG_RADIO_SI4713=m
+CONFIG_USB_MR800=m
+CONFIG_USB_DSBR=m
+CONFIG_RADIO_SHARK=m
+CONFIG_RADIO_SHARK2=m
+CONFIG_USB_KEENE=m
+CONFIG_USB_MA901=m
+CONFIG_RADIO_TEA5764=m
+CONFIG_RADIO_SAA7706H=m
+CONFIG_RADIO_TEF6862=m
+CONFIG_RADIO_WL1273=m
+CONFIG_RADIO_WL128X=m
CONFIG_FB=y
+CONFIG_FB_BCM2708=y
+# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
@@ -227,8 +747,10 @@ CONFIG_SND_BCM2835=m
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_6FIRE=m
CONFIG_SOUND_PRIME=m
+CONFIG_HIDRAW=y
CONFIG_HID_A4TECH=m
CONFIG_HID_ACRUX=m
CONFIG_HID_APPLE=m
@@ -267,9 +789,11 @@ CONFIG_HID_SUNPLUS=m
CONFIG_HID_GREENASIA=m
CONFIG_HID_SMARTJOYPLUS=m
CONFIG_HID_TOPSEED=m
+CONFIG_HID_THINGM=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_HID_WACOM=m
CONFIG_HID_WIIMOTE=m
+CONFIG_HID_XINMO=m
CONFIG_HID_ZEROPLUS=m
CONFIG_HID_ZYDACRON=m
CONFIG_HID_PID=y
@@ -277,6 +801,8 @@ CONFIG_USB_HIDDEV=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=m
+CONFIG_USB_DWCOTG=y
+CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_USB_STORAGE_DATAFAB=m
@@ -311,6 +837,7 @@ CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_F81232=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
@@ -319,6 +846,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_METRO=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_NAVMAN=m
@@ -336,7 +864,10 @@ CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_OPTICON=m
+CONFIG_USB_SERIAL_XSENS_MT=m
+CONFIG_USB_SERIAL_WISHBONE=m
CONFIG_USB_SERIAL_SSU100=m
+CONFIG_USB_SERIAL_QT2=m
CONFIG_USB_SERIAL_DEBUG=m
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
@@ -357,12 +888,81 @@ CONFIG_USB_IOWARRIOR=m
CONFIG_USB_TEST=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SPI=m
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1374=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS3232=m
+CONFIG_RTC_DRV_MAX6900=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_ISL12022=m
+CONFIG_RTC_DRV_ISL12057=m
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_PCF2127=m
+CONFIG_RTC_DRV_PCF8523=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_M41T80=m
+CONFIG_RTC_DRV_BQ32K=m
+CONFIG_RTC_DRV_S35390A=m
+CONFIG_RTC_DRV_FM3130=m
+CONFIG_RTC_DRV_RX8581=m
+CONFIG_RTC_DRV_RX8025=m
+CONFIG_RTC_DRV_EM3027=m
+CONFIG_RTC_DRV_RV3029C2=m
+CONFIG_RTC_DRV_M41T93=m
+CONFIG_RTC_DRV_M41T94=m
+CONFIG_RTC_DRV_DS1305=m
+CONFIG_RTC_DRV_DS1390=m
+CONFIG_RTC_DRV_MAX6902=m
+CONFIG_RTC_DRV_R9701=m
+CONFIG_RTC_DRV_RS5C348=m
+CONFIG_RTC_DRV_DS3234=m
+CONFIG_RTC_DRV_PCF2123=m
+CONFIG_RTC_DRV_RX4581=m
CONFIG_UIO=m
CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_STAGING=y
+CONFIG_PRISM2_USB=m
+CONFIG_R8712U=m
+CONFIG_R8188EU=m
+CONFIG_R8723AU=m
+CONFIG_VT6656=m
+CONFIG_SPEAKUP=m
+CONFIG_SPEAKUP_SYNTH_SOFT=m
+CONFIG_STAGING_MEDIA=y
+CONFIG_LIRC_STAGING=y
+CONFIG_LIRC_IGORPLUGUSB=m
+CONFIG_LIRC_IMON=m
+CONFIG_LIRC_RPI=m
+CONFIG_LIRC_SASEM=m
+CONFIG_LIRC_SERIAL=m
# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON=m
+CONFIG_EXTCON_ARIZONA=m
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
@@ -384,6 +984,8 @@ CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m
CONFIG_FANOTIFY=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=y
CONFIG_FUSE_FS=m
CONFIG_CUSE=m
@@ -399,18 +1001,26 @@ CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_CONFIGFS_FS=y
+CONFIG_ECRYPT_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
CONFIG_SQUASHFS=m
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
+CONFIG_F2FS_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
CONFIG_CIFS=m
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_XATTR=y
@@ -455,36 +1065,40 @@ CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
CONFIG_PRINTK_TIME=y
CONFIG_BOOT_PRINTK_DELAY=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
CONFIG_LATENCYTOP=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_STACK_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_KPROBE_EVENT is not set
CONFIG_FUNCTION_PROFILER=y
CONFIG_KGDB=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
CONFIG_STRICT_DEVMEM=y
-CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_USER=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_ARM=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_ITU_T=y
--
1.8.3.2

View file

@ -0,0 +1,73 @@
From 32839a570568823b3a1128bb1ae6c5fe3e9870af Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Dec 2013 22:16:19 +0000
Subject: [PATCH 024/114] config: Enable CONFIG_MEMCG, but leave it disabled
(due to memory cost). Enable with cgroup_enable=memory.
---
arch/arm/configs/bcmrpi_defconfig | 1 +
kernel/cgroup.c | 23 +++++++++++++++++++++++
mm/memcontrol.c | 1 +
3 files changed, 25 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index e2da9da..897616c 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -19,6 +19,7 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 136ecea..c909506 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5322,6 +5322,29 @@ static int __init cgroup_disable(char *str)
}
__setup("cgroup_disable=", cgroup_disable);
+static int __init cgroup_enable(char *str)
+{
+ struct cgroup_subsys *ss;
+ char *token;
+ int i;
+
+ while ((token = strsep(&str, ",")) != NULL) {
+ if (!*token)
+ continue;
+
+ for_each_subsys(ss, i) {
+ if (!strcmp(token, ss->name)) {
+ ss->disabled = 0;
+ printk(KERN_INFO "Enabling %s control group"
+ " subsystem\n", ss->name);
+ break;
+ }
+ }
+ }
+ return 1;
+}
+__setup("cgroup_enable=", cgroup_enable);
+
static int __init cgroup_set_legacy_files_on_dfl(char *str)
{
printk("cgroup: using legacy files on the default hierarchy\n");
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4918b6e..168498c 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6207,6 +6207,7 @@ struct cgroup_subsys memory_cgrp_subsys = {
.bind = mem_cgroup_bind,
.legacy_cftypes = mem_cgroup_files,
.early_init = 0,
+ .disabled = 1,
};
#ifdef CONFIG_MEMCG_SWAP
--
1.8.3.2

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,130 @@
From c3294683a11a781ec75c31d0717bee4f6438c6e6 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:59:51 +0100
Subject: [PATCH 031/114] ASoC: Add support for PCM5102A codec
Some definitions to support the PCM5102A codec
by Texas Instruments.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
sound/soc/codecs/Kconfig | 4 +++
sound/soc/codecs/Makefile | 2 ++
sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+)
create mode 100644 sound/soc/codecs/pcm5102a.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index a68d173..0ef8bb7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -80,6 +80,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM512x_I2C if I2C
select SND_SOC_PCM512x_SPI if SPI_MASTER
select SND_SOC_RT286 if I2C
+ select SND_SOC_PCM5102A if I2C
select SND_SOC_RT5631 if I2C
select SND_SOC_RT5640 if I2C
select SND_SOC_RT5645 if I2C
@@ -486,6 +487,9 @@ config SND_SOC_RT286
tristate
depends on I2C
+config SND_SOC_PCM5102A
+ tristate
+
config SND_SOC_RT5631
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5dce451..7b606e6 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -74,6 +74,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rl6231-objs := rl6231.o
snd-soc-rt286-objs := rt286.o
+snd-soc-pcm5102a-objs := pcm5102a.o
snd-soc-rt5631-objs := rt5631.o
snd-soc-rt5640-objs := rt5640.o
snd-soc-rt5645-objs := rt5645.o
@@ -250,6 +251,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
+obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
new file mode 100644
index 0000000..126f1e9
--- /dev/null
+++ b/sound/soc/codecs/pcm5102a.c
@@ -0,0 +1,63 @@
+/*
+ * Driver for the PCM5102A codec
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_dai_driver pcm5102a_dai = {
+ .name = "pcm5102a-hifi",
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE
+ },
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
+
+static int pcm5102a_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
+ &pcm5102a_dai, 1);
+}
+
+static int pcm5102a_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver pcm5102a_codec_driver = {
+ .probe = pcm5102a_probe,
+ .remove = pcm5102a_remove,
+ .driver = {
+ .name = "pcm5102a-codec",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(pcm5102a_codec_driver);
+
+MODULE_DESCRIPTION("ASoC PCM5102A codec driver");
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,60 @@
From 92f48ad219db73d6fb34f909965622ca4067da4f Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:04:54 +0100
Subject: [PATCH 032/114] BCM2708: Add I2S support to board file
Adds the required initializations for I2S
to the board file of mach-bcm2708.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index a740344..dca28ad 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -587,6 +587,28 @@ static struct platform_device bcm2835_thermal_device = {
.name = "bcm2835_thermal",
};
+#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
+static struct resource bcm2708_i2s_resources[] = {
+ {
+ .start = I2S_BASE,
+ .end = I2S_BASE + 0x20,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PCM_CLOCK_BASE,
+ .end = PCM_CLOCK_BASE + 0x02,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device bcm2708_i2s_device = {
+ .name = "bcm2708-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources),
+ .resource = bcm2708_i2s_resources,
+};
+#endif
+
int __init bcm_register_device(struct platform_device *pdev)
{
int ret;
@@ -707,6 +729,10 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2835_hwmon_device);
bcm_register_device(&bcm2835_thermal_device);
+#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
+ bcm_register_device(&bcm2708_i2s_device);
+#endif
+
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
--
1.8.3.2

View file

@ -0,0 +1,154 @@
From 77afe84c37210adb241e9b48f1a415f49f183a68 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:19:08 +0100
Subject: [PATCH 033/114] ASoC: Add support for HifiBerry DAC
This adds a machine driver for the HifiBerry DAC.
It is a sound card that can
be stacked onto the Raspberry Pi.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
sound/soc/bcm/Kconfig | 7 +++
sound/soc/bcm/Makefile | 5 +++
sound/soc/bcm/hifiberry_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+)
create mode 100644 sound/soc/bcm/hifiberry_dac.c
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 7e5b945..b36a62f 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -18,3 +18,10 @@ config SND_BCM2708_SOC_I2S
Say Y or M if you want to add support for codecs attached to
the BCM2708 I2S interface. You will also need
to select the audio interfaces to support below.
+
+config SND_BCM2708_SOC_HIFIBERRY_DAC
+ tristate "Support for HifiBerry DAC"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_PCM5102A
+ help
+ Say Y or M if you want to add support for HifiBerry DAC.
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index f8bbe1f..be90a49cb 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -7,3 +7,8 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o
obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
+
+# BCM2708 Machine Support
+snd-soc-hifiberry-dac-objs := hifiberry_dac.o
+
+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c
new file mode 100644
index 0000000..4b70b45
--- /dev/null
+++ b/sound/soc/bcm/hifiberry_dac.c
@@ -0,0 +1,100 @@
+/*
+ * ASoC Driver for HifiBerry DAC
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+static int snd_rpi_hifiberry_dac_init(struct snd_soc_pcm_runtime *rtd)
+{
+ return 0;
+}
+
+static int snd_rpi_hifiberry_dac_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ unsigned int sample_bits =
+ snd_pcm_format_physical_width(params_format(params));
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_hifiberry_dac_ops = {
+ .hw_params = snd_rpi_hifiberry_dac_hw_params,
+};
+
+static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = {
+{
+ .name = "HifiBerry DAC",
+ .stream_name = "HifiBerry DAC HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "pcm5102a-hifi",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "pcm5102a-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &snd_rpi_hifiberry_dac_ops,
+ .init = snd_rpi_hifiberry_dac_init,
+},
+};
+
+/* audio machine driver */
+static struct snd_soc_card snd_rpi_hifiberry_dac = {
+ .name = "snd_rpi_hifiberry_dac",
+ .dai_link = snd_rpi_hifiberry_dac_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai),
+};
+
+static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_hifiberry_dac.dev = &pdev->dev;
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac);
+ if (ret)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dac);
+}
+
+static struct platform_driver snd_rpi_hifiberry_dac_driver = {
+ .driver = {
+ .name = "snd-hifiberry-dac",
+ .owner = THIS_MODULE,
+ },
+ .probe = snd_rpi_hifiberry_dac_probe,
+ .remove = snd_rpi_hifiberry_dac_remove,
+};
+
+module_platform_driver(snd_rpi_hifiberry_dac_driver);
+
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,53 @@
From 75d90451c5929bc54e169ac92fc3faf234f28543 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:21:34 +0100
Subject: [PATCH 034/114] BCM2708: Add HifiBerry DAC to board file
This adds the initalization of the HifiBerry DAC
to the mach-bcm2708 board file.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index dca28ad..50d4991 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -609,6 +609,20 @@ static struct platform_device bcm2708_i2s_device = {
};
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE)
+static struct platform_device snd_hifiberry_dac_device = {
+ .name = "snd-hifiberry-dac",
+ .id = 0,
+ .num_resources = 0,
+};
+
+static struct platform_device snd_pcm5102a_codec_device = {
+ .name = "pcm5102a-codec",
+ .id = -1,
+ .num_resources = 0,
+};
+#endif
+
int __init bcm_register_device(struct platform_device *pdev)
{
int ret;
@@ -733,6 +747,11 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2708_i2s_device);
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE)
+ bcm_register_device(&snd_hifiberry_dac_device);
+ bcm_register_device(&snd_pcm5102a_codec_device);
+#endif
+
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
--
1.8.3.2

View file

@ -0,0 +1,40 @@
From dc87b04d76f021cc710a986285bee4ca722b55fd Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Mon, 2 Dec 2013 20:28:22 +0100
Subject: [PATCH 035/114] BCM2708: Add I2S and DMA support to default config
This commit adds several modules that are needed for
I2S support for the Raspberry Pi to the defconfig.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
arch/arm/configs/bcmrpi_defconfig | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 3f99687..dfd98df 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -753,6 +753,10 @@ CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_CAIAQ=m
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_6FIRE=m
+CONFIG_SND_SOC=m
+CONFIG_SND_BCM2708_SOC_I2S=m
+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
+CONFIG_SND_SIMPLE_CARD=m
CONFIG_SOUND_PRIME=m
CONFIG_HIDRAW=y
CONFIG_HID_A4TECH=m
@@ -947,6 +951,8 @@ CONFIG_RTC_DRV_RS5C348=m
CONFIG_RTC_DRV_DS3234=m
CONFIG_RTC_DRV_PCF2123=m
CONFIG_RTC_DRV_RX4581=m
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BCM2708=y
CONFIG_UIO=m
CONFIG_UIO_PDRV_GENIRQ=m
CONFIG_STAGING=y
--
1.8.3.2

View file

@ -0,0 +1,313 @@
From 52fceff596533a847231d1f9b8ea13d4e6ee829b Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 6 Dec 2013 20:50:28 +0100
Subject: [PATCH 036/114] ASoC: BCM2708: Add support for RPi-DAC
This adds a machine driver for the RPi-DAC.
Signed-off-by: Florian Meier <florian.meier@koalo.de>
---
arch/arm/configs/bcmrpi_defconfig | 1 +
arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++
sound/soc/bcm/Kconfig | 7 +++
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/Kconfig | 4 ++
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/pcm1794a.c | 62 +++++++++++++++++++++++++
8 files changed, 194 insertions(+)
create mode 100644 sound/soc/bcm/rpi-dac.c
create mode 100644 sound/soc/codecs/pcm1794a.c
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index dfd98df..f688da5 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m
CONFIG_SND_SOC=m
CONFIG_SND_BCM2708_SOC_I2S=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
+CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SOUND_PRIME=m
CONFIG_HIDRAW=y
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 50d4991..100c223 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -623,6 +623,20 @@ static struct platform_device snd_pcm5102a_codec_device = {
};
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
+static struct platform_device snd_rpi_dac_device = {
+ .name = "snd-rpi-dac",
+ .id = 0,
+ .num_resources = 0,
+};
+
+static struct platform_device snd_pcm1794a_codec_device = {
+ .name = "pcm1794a-codec",
+ .id = -1,
+ .num_resources = 0,
+};
+#endif
+
int __init bcm_register_device(struct platform_device *pdev)
{
int ret;
@@ -752,6 +766,11 @@ void __init bcm2708_init(void)
bcm_register_device(&snd_pcm5102a_codec_device);
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
+ bcm_register_device(&snd_rpi_dac_device);
+ bcm_register_device(&snd_pcm1794a_codec_device);
+#endif
+
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index b36a62f..714841d 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -25,3 +25,10 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC
select SND_SOC_PCM5102A
help
Say Y or M if you want to add support for HifiBerry DAC.
+
+config SND_BCM2708_SOC_RPI_DAC
+ tristate "Support for RPi-DAC"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_PCM1794A
+ help
+ Say Y or M if you want to add support for RPi-DAC.
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index be90a49cb..ccc9809 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -10,5 +10,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
# BCM2708 Machine Support
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
+snd-soc-rpi-dac-objs := rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
+obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c
new file mode 100644
index 0000000..6d6e0ba
--- /dev/null
+++ b/sound/soc/bcm/rpi-dac.c
@@ -0,0 +1,97 @@
+/*
+ * ASoC Driver for RPi-DAC.
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+static int snd_rpi_rpi_dac_init(struct snd_soc_pcm_runtime *rtd)
+{
+ return 0;
+}
+
+static int snd_rpi_rpi_dac_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_rpi_dac_ops = {
+ .hw_params = snd_rpi_rpi_dac_hw_params,
+};
+
+static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = {
+{
+ .name = "RPi-DAC",
+ .stream_name = "RPi-DAC HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "pcm1794a-hifi",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "pcm1794a-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &snd_rpi_rpi_dac_ops,
+ .init = snd_rpi_rpi_dac_init,
+},
+};
+
+/* audio machine driver */
+static struct snd_soc_card snd_rpi_rpi_dac = {
+ .name = "snd_rpi_rpi_dac",
+ .dai_link = snd_rpi_rpi_dac_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai),
+};
+
+static int snd_rpi_rpi_dac_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_rpi_dac.dev = &pdev->dev;
+ ret = snd_soc_register_card(&snd_rpi_rpi_dac);
+ if (ret)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int snd_rpi_rpi_dac_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_rpi_dac);
+}
+
+static struct platform_driver snd_rpi_rpi_dac_driver = {
+ .driver = {
+ .name = "snd-rpi-dac",
+ .owner = THIS_MODULE,
+ },
+ .probe = snd_rpi_rpi_dac_probe,
+ .remove = snd_rpi_rpi_dac_remove,
+};
+
+module_platform_driver(snd_rpi_rpi_dac_driver);
+
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_DESCRIPTION("ASoC Driver for RPi-DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0ef8bb7..3c236a6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -81,6 +81,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM512x_SPI if SPI_MASTER
select SND_SOC_RT286 if I2C
select SND_SOC_PCM5102A if I2C
+ select SND_SOC_PCM1794A if I2C
select SND_SOC_RT5631 if I2C
select SND_SOC_RT5640 if I2C
select SND_SOC_RT5645 if I2C
@@ -487,6 +488,9 @@ config SND_SOC_RT286
tristate
depends on I2C
+config SND_SOC_PCM1794A
+ tristate
+
config SND_SOC_PCM5102A
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7b606e6..2a7f823 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -74,6 +74,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rl6231-objs := rl6231.o
snd-soc-rt286-objs := rt286.o
+snd-soc-pcm1794a-objs := pcm1794a.o
snd-soc-pcm5102a-objs := pcm5102a.o
snd-soc-rt5631-objs := rt5631.o
snd-soc-rt5640-objs := rt5640.o
@@ -251,6 +252,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
+obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o
obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
diff --git a/sound/soc/codecs/pcm1794a.c b/sound/soc/codecs/pcm1794a.c
new file mode 100644
index 0000000..b4eaa44
--- /dev/null
+++ b/sound/soc/codecs/pcm1794a.c
@@ -0,0 +1,62 @@
+/*
+ * Driver for the PCM1794A codec
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_dai_driver pcm1794a_dai = {
+ .name = "pcm1794a-hifi",
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE
+ },
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_pcm1794a;
+
+static int pcm1794a_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm1794a,
+ &pcm1794a_dai, 1);
+}
+
+static int pcm1794a_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver pcm1794a_codec_driver = {
+ .probe = pcm1794a_probe,
+ .remove = pcm1794a_remove,
+ .driver = {
+ .name = "pcm1794a-codec",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(pcm1794a_codec_driver);
+
+MODULE_DESCRIPTION("ASoC PCM1794A codec driver");
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,45 @@
From f33231bfe57c745235a346d5529a4bac717d925e Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:41:23 +0100
Subject: [PATCH 037/114] ASoC: wm8804: Implement MCLK configuration options,
add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs
for most sample rates. At 192kHz only 128xfs is supported. The existing
driver selects 128xfs automatically for some lower samples rates. By using an
additional mclk_div divider, it is now possible to control the behaviour.
This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It
should allow lower jitter and better signal quality. The behavior has to be
controlled by the sound card driver, because some sample frequency share the
same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only
difference is the MCLK divider.
This also added support for 32bit data.
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
---
sound/soc/codecs/wm8804.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 3addc5f..d060b23 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -278,6 +278,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
blen = 0x1;
break;
case 24:
+ case 32:
blen = 0x2;
break;
default:
@@ -624,7 +625,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = {
};
#define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
#define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
--
1.8.3.2

View file

@ -0,0 +1,208 @@
From bccfebf3bc4457faddaa65e3492ec9f07cb5750b Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:42:08 +0100
Subject: [PATCH 038/114] ASoC: BCM:Add support for HiFiBerry Digi. Driver is
based on the patched WM8804 driver.
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
---
sound/soc/bcm/Kconfig | 7 ++
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/hifiberry_digi.c | 153 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 162 insertions(+)
create mode 100644 sound/soc/bcm/hifiberry_digi.c
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 714841d..e563dbc 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC
help
Say Y or M if you want to add support for HifiBerry DAC.
+config SND_BCM2708_SOC_HIFIBERRY_DIGI
+ tristate "Support for HifiBerry Digi"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_WM8804
+ help
+ Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board.
+
config SND_BCM2708_SOC_RPI_DAC
tristate "Support for RPi-DAC"
depends on SND_BCM2708_SOC_I2S
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index ccc9809..826df7d 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -10,7 +10,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
# BCM2708 Machine Support
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
+snd-soc-hifiberry-digi-objs := hifiberry_digi.o
snd-soc-rpi-dac-objs := rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c
new file mode 100644
index 0000000..e4f769d
--- /dev/null
+++ b/sound/soc/bcm/hifiberry_digi.c
@@ -0,0 +1,153 @@
+/*
+ * ASoC Driver for HifiBerry Digi
+ *
+ * Author: Daniel Matuschek <info@crazy-audio.com>
+ * based on the HifiBerry DAC driver by Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+#include "../codecs/wm8804.h"
+
+static int samplerate=44100;
+
+static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+
+ /* enable TX output */
+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
+
+ return 0;
+}
+
+static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ int sysclk = 27000000; /* This is fixed on this board */
+
+ long mclk_freq=0;
+ int mclk_div=1;
+
+ int ret;
+
+ samplerate = params_rate(params);
+
+ switch (samplerate) {
+ case 44100:
+ case 48000:
+ case 88200:
+ case 96000:
+ mclk_freq=samplerate*256;
+ mclk_div=WM8804_MCLKDIV_256FS;
+ break;
+ case 176400:
+ case 192000:
+ mclk_freq=samplerate*128;
+ mclk_div=WM8804_MCLKDIV_128FS;
+ break;
+ default:
+ dev_err(substream->pcm->dev,
+ "Failed to set WM8804 SYSCLK, unsupported samplerate\n");
+ }
+
+ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div);
+ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq);
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
+ sysclk, SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ dev_err(substream->pcm->dev,
+ "Failed to set WM8804 SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable TX output */
+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
+
+ /* Power on */
+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai,64);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = {
+ .hw_params = snd_rpi_hifiberry_digi_hw_params,
+};
+
+static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = {
+{
+ .name = "HifiBerry Digi",
+ .stream_name = "HifiBerry Digi HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "wm8804-spdif",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "wm8804.1-003b",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM,
+ .ops = &snd_rpi_hifiberry_digi_ops,
+ .init = snd_rpi_hifiberry_digi_init,
+},
+};
+
+/* audio machine driver */
+static struct snd_soc_card snd_rpi_hifiberry_digi = {
+ .name = "snd_rpi_hifiberry_digi",
+ .dai_link = snd_rpi_hifiberry_digi_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai),
+};
+
+static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_hifiberry_digi.dev = &pdev->dev;
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);
+ if (ret)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_hifiberry_digi);
+}
+
+static struct platform_driver snd_rpi_hifiberry_digi_driver = {
+ .driver = {
+ .name = "snd-hifiberry-digi",
+ .owner = THIS_MODULE,
+ },
+ .probe = snd_rpi_hifiberry_digi_probe,
+ .remove = snd_rpi_hifiberry_digi_remove,
+};
+
+module_platform_driver(snd_rpi_hifiberry_digi_driver);
+
+MODULE_AUTHOR("Daniel Matuschek <info@crazy-audio.com>");
+MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,52 @@
From 2a04dad39006e26f9ee4c56e78255d5e4dc20075 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Thu, 16 Jan 2014 07:26:08 +0100
Subject: [PATCH 039/114] BCM2708: Added support for HiFiBerry Digi board Board
initalization by I2C
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
---
arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 100c223..a57cb85 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -623,6 +623,21 @@ static struct platform_device snd_pcm5102a_codec_device = {
};
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
+static struct platform_device snd_hifiberry_digi_device = {
+ .name = "snd-hifiberry-digi",
+ .id = 0,
+ .num_resources = 0,
+};
+
+static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("wm8804", 0x3b)
+ },
+};
+
+#endif
+
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
static struct platform_device snd_rpi_dac_device = {
.name = "snd-rpi-dac",
@@ -766,6 +781,11 @@ void __init bcm2708_init(void)
bcm_register_device(&snd_pcm5102a_codec_device);
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
+ bcm_register_device(&snd_hifiberry_digi_device);
+ i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
+#endif
+
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
bcm_register_device(&snd_rpi_dac_device);
bcm_register_device(&snd_pcm1794a_codec_device);
--
1.8.3.2

View file

@ -0,0 +1,27 @@
From 7ea75f6521191c234c02d6849388bb3ad5071754 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Thu, 16 Jan 2014 07:27:28 +0100
Subject: [PATCH 040/114] BCM2708: Added HiFiBerry Digi configuration option It
will be compiled as a module by default. This also includes the WM8804
driver.
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
---
arch/arm/configs/bcmrpi_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index f688da5..c9d3fac 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m
CONFIG_SND_SOC=m
CONFIG_SND_BCM2708_SOC_I2S=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SOUND_PRIME=m
--
1.8.3.2

View file

@ -0,0 +1,27 @@
From 999241ea1ab8a7b1526f41c100cd636ab3511fe9 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Thu, 16 Jan 2014 07:36:35 +0100
Subject: [PATCH 041/114] ASoC: wm8804: Set idle_bias_off to false Idle bias
has been change to remove warning on driver startup
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
---
sound/soc/codecs/wm8804.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index d060b23..d486a9d 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -656,7 +656,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
.probe = wm8804_probe,
.remove = wm8804_remove,
.set_bias_level = wm8804_set_bias_level,
- .idle_bias_off = true,
+ .idle_bias_off = false,
.controls = wm8804_snd_controls,
.num_controls = ARRAY_SIZE(wm8804_snd_controls),
--
1.8.3.2

View file

@ -0,0 +1,215 @@
From 19b5aa63015268ce3c736b720e1e7f8211f7cf98 Mon Sep 17 00:00:00 2001
From: Gordon Garrity <gordon@iqaudio.com>
Date: Sat, 8 Mar 2014 16:56:57 +0000
Subject: [PATCH 042/114] Add IQaudIO Sound Card support for Raspberry Pi
---
arch/arm/configs/bcmrpi_defconfig | 1 +
arch/arm/mach-bcm2708/bcm2708.c | 22 ++++++++
sound/soc/bcm/Kconfig | 7 +++
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/iqaudio-dac.c | 111 ++++++++++++++++++++++++++++++++++++++
5 files changed, 143 insertions(+)
create mode 100644 sound/soc/bcm/iqaudio-dac.c
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index c9d3fac..f15a4b9 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -758,6 +758,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SOUND_PRIME=m
CONFIG_HIDRAW=y
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index a57cb85..633be19 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -652,6 +652,22 @@ static struct platform_device snd_pcm1794a_codec_device = {
};
#endif
+
+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
+static struct platform_device snd_rpi_iqaudio_dac_device = {
+ .name = "snd-rpi-iqaudio-dac",
+ .id = 0,
+ .num_resources = 0,
+};
+
+// Use the actual device name rather than generic driver name
+static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcm5122", 0x4c)
+ },
+};
+#endif
+
int __init bcm_register_device(struct platform_device *pdev)
{
int ret;
@@ -791,6 +807,12 @@ void __init bcm2708_init(void)
bcm_register_device(&snd_pcm1794a_codec_device);
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
+ bcm_register_device(&snd_rpi_iqaudio_dac_device);
+ i2c_register_board_info(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
+#endif
+
+
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index e563dbc..c621a5e 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC
select SND_SOC_PCM1794A
help
Say Y or M if you want to add support for RPi-DAC.
+
+config SND_BCM2708_SOC_IQAUDIO_DAC
+ tristate "Support for IQaudIO-DAC"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_PCM512x_I2C
+ help
+ Say Y or M if you want to add support for IQaudIO-DAC.
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index 826df7d..d597fb0 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
snd-soc-rpi-dac-objs := rpi-dac.o
+snd-soc-iqaudio-dac-objs := iqaudio-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
+obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c
new file mode 100644
index 0000000..8d0e2ae
--- /dev/null
+++ b/sound/soc/bcm/iqaudio-dac.c
@@ -0,0 +1,111 @@
+/*
+ * ASoC Driver for IQaudIO DAC
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd)
+{
+// NOT USED struct snd_soc_codec *codec = rtd->codec;
+
+ return 0;
+}
+
+static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+// NOT USED struct snd_soc_dai *codec_dai = rtd->codec_dai;
+// NOT USED struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ unsigned int sample_bits =
+ snd_pcm_format_physical_width(params_format(params));
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = {
+ .hw_params = snd_rpi_iqaudio_dac_hw_params,
+};
+
+static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = {
+{
+ .name = "IQaudIO DAC",
+ .stream_name = "IQaudIO DAC HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "pcm512x-hifi",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "pcm512x.1-004c",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &snd_rpi_iqaudio_dac_ops,
+ .init = snd_rpi_iqaudio_dac_init,
+},
+};
+
+/* audio machine driver */
+static struct snd_soc_card snd_rpi_iqaudio_dac = {
+ .name = "IQaudIODAC",
+ .dai_link = snd_rpi_iqaudio_dac_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai),
+};
+
+static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_iqaudio_dac.dev = &pdev->dev;
+ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
+ if (ret)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_iqaudio_dac);
+}
+
+static const struct of_device_id iqaudio_of_match[] = {
+ { .compatible = "iqaudio,iqaudio-dac", },
+ {},
+};
+
+static struct platform_driver snd_rpi_iqaudio_dac_driver = {
+ .driver = {
+ .name = "snd-rpi-iqaudio-dac",
+ .owner = THIS_MODULE,
+ .of_match_table = iqaudio_of_match,
+ },
+ .probe = snd_rpi_iqaudio_dac_probe,
+ .remove = snd_rpi_iqaudio_dac_remove,
+};
+
+module_platform_driver(snd_rpi_iqaudio_dac_driver);
+
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,30 @@
From 197803c176d753bc23fdf705306596cbd1e8b658 Mon Sep 17 00:00:00 2001
From: Howard Mitchell <hm@hmbedded.co.uk>
Date: Fri, 28 Mar 2014 16:40:31 +0000
Subject: [PATCH 043/114] pcm512x: Use a range macro for Volume and rename to
PCM.
This allows limiting the output gain to avoid clipping in the
DAC ouput stages.
---
sound/soc/codecs/pcm512x.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 640c991..b405719 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -259,8 +259,8 @@ static const struct soc_enum pcm512x_veds =
pcm512x_ramp_step_text);
static const struct snd_kcontrol_new pcm512x_controls[] = {
-SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
- PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
+SOC_DOUBLE_R_RANGE_TLV("PCM", PCM512x_DIGITAL_VOLUME_2,
+ PCM512x_DIGITAL_VOLUME_3, 0, 40, 255, 1, digital_tlv),
SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
--
1.8.3.2

View file

@ -0,0 +1,32 @@
From de30840b98e508ea9d650570686e35b1a64c900c Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Jun 2014 13:42:01 +0100
Subject: [PATCH 044/114] vmstat: Workaround for issue where dirty page count
goes negative
See:
https://github.com/raspberrypi/linux/issues/617
http://www.spinics.net/lists/linux-mm/msg72236.html
---
include/linux/vmstat.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 82e7db7..f87d16d 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
{
atomic_long_dec(&zone->vm_stat[item]);
+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0))
+ atomic_long_set(&zone->vm_stat[item], 0);
atomic_long_dec(&vm_stat[item]);
+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0))
+ atomic_long_set(&vm_stat[item], 0);
}
static inline void __inc_zone_page_state(struct page *page,
--
1.8.3.2

View file

@ -0,0 +1,75 @@
From 8eb79690a70cce34e9a1c35cf165716f78301d2e Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Fri, 20 Jun 2014 16:03:12 +0100
Subject: [PATCH 045/114] dwc_otg: Fix various issues with root port and
transaction errors
Process the host port interrupts correctly (and don't trample them).
Root port hotplug now functional again.
Fix a few thinkos with the transaction error passthrough for fiq_fsm.
---
drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 7 +++----
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 6 +++++-
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2 +-
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
index 065807f..96c76e3 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
@@ -1348,10 +1348,9 @@ static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gin
local_fiq_disable();
/* Pull in the interrupts that the FIQ has masked */
gintmsk.d32 |= ~(hcd->fiq_state->gintmsk_saved.d32);
+ gintmsk.d32 |= gintmsk_common.d32;
/* for the upstairs function to reenable - have to read it here in case FIQ triggers again */
- reenable_gintmsk->d32 |= gintmsk.d32;
- reenable_gintmsk->d32 |= ~(hcd->fiq_state->gintmsk_saved.d32);
- reenable_gintmsk->d32 &= gintmsk_common.d32;
+ reenable_gintmsk->d32 = gintmsk.d32;
local_fiq_enable();
}
@@ -1535,7 +1534,7 @@ int32_t dwc_otg_handle_common_intr(void *dev)
// fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "CILOUT %1d", retval);
// fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintsts.d32);
// fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintmsk_reenable.d32);
- if (retval) {
+ if (retval && fiq_enable) {
DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_reenable.d32);
}
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
index 1be6e71..284f902 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
@@ -696,7 +696,11 @@ static int notrace noinline fiq_fsm_do_hcintr(struct fiq_state *state, int num_c
fiq_print(FIQDBG_ERR, state, "ERRST %02d", n);
if (hcint_probe.b.nak || hcint_probe.b.ack || hcint_probe.b.datatglerr) {
fiq_print(FIQDBG_ERR, state, "RESET %02d", n);
- st->nr_errors = 0;
+ /* In some random cases we can get a NAK interrupt coincident with a Xacterr
+ * interrupt, after the device has disappeared.
+ */
+ if (!hcint.b.xacterr)
+ st->nr_errors = 0;
hcintmsk.b.nak = 0;
hcintmsk.b.ack = 0;
hcintmsk.b.datatglerr = 0;
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
index 4195ff2..a5566bc 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
@@ -2619,7 +2619,7 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, uint32_t num)
case FIQ_PASSTHROUGH_ERRORSTATE:
/* Hook into the error count */
fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "HCDERR%02d", num);
- if (dwc_otg_hcd->fiq_state->channel[num].nr_errors) {
+ if (!dwc_otg_hcd->fiq_state->channel[num].nr_errors) {
qtd->error_count = 0;
fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "RESET ");
}
--
1.8.3.2

View file

@ -0,0 +1,91 @@
From 099581aeb11b7eafbca02c9e69f6e6c8de0c57ec Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Fri, 20 Jun 2014 17:23:20 +0100
Subject: [PATCH 046/114] fiq_fsm: Implement hack for Split Interrupt
transactions
Hubs aren't too picky about which endpoint we send Control type split
transactions to. By treating Interrupt transfers as Control, it is
possible to use the non-periodic queue in the OTG core as well as the
non-periodic FIFOs in the hub itself. This massively reduces the
microframe exclusivity/contention that periodic split transactions
otherwise have to enforce.
It goes without saying that this is a fairly egregious USB specification
violation, but it works.
Original idea by Hans Petter Selasky @ FreeBSD.org.
---
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
index 130096b..68d4f3b 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
@@ -1055,10 +1055,11 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if)
for (i=0; i < hcd->core_if->core_params->host_channels; i++) {
dwc_otg_cleanup_fiq_channel(hcd, i);
}
- DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s",
+ DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s%s",
(fiq_fsm_mask & 0x1) ? "Non-periodic Split Transactions\n" : "",
(fiq_fsm_mask & 0x2) ? "Periodic Split Transactions\n" : "",
- (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "");
+ (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "",
+ (fiq_fsm_mask & 0x8) ? "Interrupt/Control Split Transaction hack enabled\n" : "");
}
}
@@ -1789,6 +1790,20 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
st->hcintmsk_copy.b.chhltd = 1;
st->hcintmsk_copy.b.ahberr = 1;
+ /* Hack courtesy of FreeBSD: apparently forcing Interrupt Split transactions
+ * as Control puts the transfer into the non-periodic request queue and the
+ * non-periodic handler in the hub. Makes things lots easier.
+ */
+ if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT) {
+ st->hcchar_copy.b.multicnt = 0;
+ st->hcchar_copy.b.oddfrm = 0;
+ st->hcchar_copy.b.eptype = UE_CONTROL;
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+ st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
+ }
+ }
DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
DWC_WRITE_REG32(&hc_regs->hctsiz, st->hctsiz_copy.d32);
DWC_WRITE_REG32(&hc_regs->hcsplt, st->hcsplt_copy.d32);
@@ -1842,6 +1857,9 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
}
}
}
+ if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT)
+ start_immediate = 1;
+
fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d %01d", hc->hc_num, start_immediate);
fiq_print(FIQDBG_INT, hcd->fiq_state, "%08d", hfnum.b.frrem);
//fiq_print(FIQDBG_INT, hcd->fiq_state, "H:%02dP:%02d", hub_addr, port_addr);
@@ -1873,11 +1891,13 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
}
break;
case UE_INTERRUPT:
- if (start_immediate) {
+ if (fiq_fsm_mask & 0x8) {
+ st->fsm = FIQ_NP_SSPLIT_STARTED;
+ } else if (start_immediate) {
st->fsm = FIQ_PER_SSPLIT_STARTED;
- } else {
- st->fsm = FIQ_PER_SSPLIT_QUEUED;
- }
+ } else {
+ st->fsm = FIQ_PER_SSPLIT_QUEUED;
+ }
default:
break;
}
--
1.8.3.2

View file

@ -0,0 +1,50 @@
From d828fe6d765939e457e87d7f348adfe69cfd4175 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Sun, 6 Jul 2014 12:07:25 +0200
Subject: [PATCH 047/114] spi-bcm2708: Prepare for Common Clock Framework
migration
As part of migrating to use the Common Clock Framework, replace clk_enable()
with clk_prepare_enable() and clk_disable() with clk_disable_unprepare().
This does not affect behaviour under the current clock implementation.
Also add a missing clk_disable_unprepare() in the probe error path.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
---
drivers/spi/spi-bcm2708.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c
index b04a57d..349d21f 100644
--- a/drivers/spi/spi-bcm2708.c
+++ b/drivers/spi/spi-bcm2708.c
@@ -545,7 +545,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev)
}
/* initialise the hardware */
- clk_enable(clk);
+ clk_prepare_enable(clk);
bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
err = spi_register_master(master);
@@ -561,6 +561,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev)
out_free_irq:
free_irq(bs->irq, master);
+ clk_disable_unprepare(bs->clk);
out_workqueue:
destroy_workqueue(bs->workq);
out_iounmap:
@@ -585,7 +586,7 @@ static int bcm2708_spi_remove(struct platform_device *pdev)
flush_work(&bs->work);
- clk_disable(bs->clk);
+ clk_disable_unprepare(bs->clk);
clk_put(bs->clk);
free_irq(bs->irq, master);
iounmap(bs->base);
--
1.8.3.2

View file

@ -0,0 +1,275 @@
From 466743ec93a99240c1a5a04d65f490fd8370fbc3 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Sun, 6 Jul 2014 12:09:30 +0200
Subject: [PATCH 048/114] BCM2708: Migrate to the Common Clock Framework
As part of moving towards using Device Tree, the Common Clock Framework
has to be used instead of the BCM2708 clock implementation.
Selecting COMMON_CLK removes the need to set CLKDEV_LOOKUP and HAVE_CLK explicitly.
CONFIG_ARCH_BCM2708_CHIPIT #ifdef's are removed. They are no longer in use.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
---
arch/arm/Kconfig | 3 +-
arch/arm/mach-bcm2708/Makefile | 2 +-
arch/arm/mach-bcm2708/bcm2708.c | 79 +++++++++++++++++------------------------
arch/arm/mach-bcm2708/clock.c | 61 -------------------------------
arch/arm/mach-bcm2708/clock.h | 24 -------------
5 files changed, 34 insertions(+), 135 deletions(-)
delete mode 100644 arch/arm/mach-bcm2708/clock.c
delete mode 100644 arch/arm/mach-bcm2708/clock.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba9c18e..0f2287f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -385,11 +385,10 @@ config ARCH_BCM2708
bool "Broadcom BCM2708 family"
select CPU_V6
select ARM_AMBA
- select HAVE_CLK
select HAVE_SCHED_CLOCK
select NEED_MACH_GPIO_H
select NEED_MACH_MEMORY_H
- select CLKDEV_LOOKUP
+ select COMMON_CLK
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARM_ERRATA_411920
diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile
index a722f3f..21e3521 100644
--- a/arch/arm/mach-bcm2708/Makefile
+++ b/arch/arm/mach-bcm2708/Makefile
@@ -2,6 +2,6 @@
# Makefile for the linux kernel.
#
-obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o
+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o dma.o
obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o
obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 633be19..ef12cb8 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -27,6 +27,8 @@
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#include <linux/clockchips.h>
#include <linux/cnt32_to_63.h>
#include <linux/io.h>
@@ -58,7 +60,6 @@
#include "bcm2708.h"
#include "armctrl.h"
-#include "clock.h"
#ifdef CONFIG_BCM_VC_CMA
#include <linux/broadcom/vc_cma.h>
@@ -84,7 +85,7 @@
/* command line parameters */
static unsigned boardrev, serial;
-static unsigned uart_clock;
+static unsigned uart_clock = UART0_CLOCK;
static unsigned disk_led_gpio = 16;
static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
@@ -196,51 +197,39 @@ static void __init bcm2708_clocksource_init(void)
}
}
+struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate)
+{
+ struct clk *clk;
-/*
- * These are fixed clocks.
- */
-static struct clk ref24_clk = {
- .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */
-};
+ clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT,
+ fixed_rate);
+ if (IS_ERR(clk))
+ pr_err("%s not registered\n", name);
-static struct clk osc_clk = {
-#ifdef CONFIG_ARCH_BCM2708_CHIPIT
- .rate = 27000000,
-#else
- .rate = 500000000, /* ARM clock is set from the VideoCore booter */
-#endif
-};
+ return clk;
+}
-/* warning - the USB needs a clock > 34MHz */
+void __init bcm2708_register_clkdev(struct clk *clk, const char *name)
+{
+ int ret;
-static struct clk sdhost_clk = {
-#ifdef CONFIG_ARCH_BCM2708_CHIPIT
- .rate = 4000000, /* 4MHz */
-#else
- .rate = 250000000, /* 250MHz */
-#endif
-};
+ ret = clk_register_clkdev(clk, NULL, name);
+ if (ret)
+ pr_err("%s alias not registered\n", name);
+}
-static struct clk_lookup lookups[] = {
- { /* UART0 */
- .dev_id = "dev:f1",
- .clk = &ref24_clk,
- },
- { /* USB */
- .dev_id = "bcm2708_usb",
- .clk = &osc_clk,
- }, { /* SPI */
- .dev_id = "bcm2708_spi.0",
- .clk = &sdhost_clk,
- }, { /* BSC0 */
- .dev_id = "bcm2708_i2c.0",
- .clk = &sdhost_clk,
- }, { /* BSC1 */
- .dev_id = "bcm2708_i2c.1",
- .clk = &sdhost_clk,
- }
-};
+void __init bcm2708_init_clocks(void)
+{
+ struct clk *clk;
+
+ clk = bcm2708_clk_register("uart0_clk", uart_clock);
+ bcm2708_register_clkdev(clk, "dev:f1");
+
+ clk = bcm2708_clk_register("sdhost_clk", 250000000);
+ bcm2708_register_clkdev(clk, "bcm2708_spi.0");
+ bcm2708_register_clkdev(clk, "bcm2708_i2c.0");
+ bcm2708_register_clkdev(clk, "bcm2708_i2c.1");
+}
#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ }
#define UART0_DMA { 15, 14 }
@@ -755,11 +744,7 @@ void __init bcm2708_init(void)
printk("bcm2708.uart_clock = %d\n", uart_clock);
pm_power_off = bcm2708_power_off;
- if (uart_clock)
- lookups[0].clk->rate = uart_clock;
-
- for (i = 0; i < ARRAY_SIZE(lookups); i++)
- clkdev_add(&lookups[i]);
+ bcm2708_init_clocks();
bcm_register_device(&bcm2708_dmaman_device);
bcm_register_device(&bcm2708_vcio_device);
diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c
deleted file mode 100644
index 4fc556e..0000000
--- a/arch/arm/mach-bcm2708/clock.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * linux/arch/arm/mach-bcm2708/clock.c
- *
- * Copyright (C) 2010 Broadcom
- *
- * 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
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/clkdev.h>
-
-#include "clock.h"
-
-int clk_enable(struct clk *clk)
-{
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- return -EIO;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h
deleted file mode 100644
index 5f9d725..0000000
--- a/arch/arm/mach-bcm2708/clock.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * linux/arch/arm/mach-bcm2708/clock.h
- *
- * Copyright (C) 2010 Broadcom
- *
- * 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
- */
-struct module;
-
-struct clk {
- unsigned long rate;
-};
--
1.8.3.2

View file

@ -0,0 +1,170 @@
From f6459ef9602c16b02516be4848a77d30ce75d168 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Wed, 9 Jul 2014 14:46:08 +0200
Subject: [PATCH 049/114] BCM2708: Add core Device Tree support
Add the bare minimum needed to boot BCM2708 from a Device Tree.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
BCM2708: DT: change 'axi' nodename to 'soc'
Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835.
The VC4 bootloader fills in certain properties in the 'axi' subtree,
but since this is part of an upstreaming effort, the name is changed.
Signed-off-by: Noralf Tronnes notro@tronnes.org
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/bcm2708-rpi-b.dts | 8 ++++++++
arch/arm/boot/dts/bcm2708.dtsi | 27 +++++++++++++++++++++++++++
arch/arm/mach-bcm2708/Kconfig | 8 ++++++++
arch/arm/mach-bcm2708/bcm2708.c | 24 ++++++++++++++++++++++++
5 files changed, 68 insertions(+)
create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts
create mode 100644 arch/arm/boot/dts/bcm2708.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 38c89ca..c727f71 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4ek.dtb
dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
new file mode 100644
index 0000000..e319c8e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/include/ "bcm2708.dtsi"
+
+/ {
+ compatible = "brcm,bcm2708";
+ model = "Raspberry Pi";
+};
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
new file mode 100644
index 0000000..50da059
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -0,0 +1,27 @@
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm2708";
+ model = "BCM2708";
+
+ chosen {
+ /*
+ bootargs must be 1024 characters long because the
+ VC bootloader can't expand it
+ */
+ bootargs = "console=ttyAMA0 ";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x7e000000 0x20000000 0x02000000>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
index e151ed4..182e7ba 100644
--- a/arch/arm/mach-bcm2708/Kconfig
+++ b/arch/arm/mach-bcm2708/Kconfig
@@ -9,6 +9,14 @@ config MACH_BCM2708
help
Include support for the Broadcom(R) BCM2708 platform.
+config BCM2708_DT
+ bool "BCM2708 Device Tree support"
+ depends on MACH_BCM2708
+ default n
+ select USE_OF
+ help
+ Enable Device Tree support for BCM2708
+
config BCM2708_GPIO
bool "BCM2708 gpio support"
depends on MACH_BCM2708
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index ef12cb8..747e27a 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -33,6 +33,7 @@
#include <linux/cnt32_to_63.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of_platform.h>
#include <linux/spi/spi.h>
#include <linux/w1-gpio.h>
@@ -734,6 +735,22 @@ static void bcm2708_power_off(void)
}
}
+#ifdef CONFIG_OF
+static void __init bcm2708_dt_init(void)
+{
+ int ret;
+
+ of_clk_init(NULL);
+ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ if (ret) {
+ pr_err("of_platform_populate failed: %d\n", ret);
+ BUG();
+ }
+}
+#else
+static void __init bcm2708_dt_init(void) { }
+#endif /* CONFIG_OF */
+
void __init bcm2708_init(void)
{
int i;
@@ -745,6 +762,7 @@ void __init bcm2708_init(void)
pm_power_off = bcm2708_power_off;
bcm2708_init_clocks();
+ bcm2708_dt_init();
bcm_register_device(&bcm2708_dmaman_device);
bcm_register_device(&bcm2708_vcio_device);
@@ -965,6 +983,11 @@ static void __init board_reserve(void)
#endif
}
+static const char * const bcm2708_compat[] = {
+ "brcm,bcm2708",
+ NULL
+};
+
MACHINE_START(BCM2708, "BCM2708")
/* Maintainer: Broadcom Europe Ltd. */
.map_io = bcm2708_map_io,
@@ -974,6 +997,7 @@ MACHINE_START(BCM2708, "BCM2708")
.init_early = bcm2708_init_early,
.reserve = board_reserve,
.restart = bcm2708_restart,
+ .dt_compat = bcm2708_compat,
MACHINE_END
module_param(boardrev, uint, 0644);
--
1.8.3.2

View file

@ -0,0 +1,175 @@
From 6be3809614db2d52724eb4b5193c27d2466142be Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Wed, 9 Jul 2014 14:47:48 +0200
Subject: [PATCH 050/114] BCM2708: armctrl: Add IRQ Device Tree support
Add Device Tree IRQ support for BCM2708.
Usage is the same as for irq-bcm2835.
See binding document: brcm,bcm2835-armctrl-ic.txt
A bank 3 is added to handle GPIO interrupts. This is done because
armctrl also handles GPIO interrupts.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
BCM2708: armctrl: remove irq bank 3
irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio
combination. It is no longer required.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
---
arch/arm/boot/dts/bcm2708.dtsi | 9 ++++
arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index 50da059..a06f5b8 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -4,6 +4,8 @@
compatible = "brcm,bcm2708";
model = "BCM2708";
+ interrupt-parent = <&intc>;
+
chosen {
/*
bootargs must be 1024 characters long because the
@@ -17,6 +19,13 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x7e000000 0x20000000 0x02000000>;
+
+ intc: interrupt-controller {
+ compatible = "brcm,bcm2708-armctrl-ic";
+ reg = <0x7e00b200 0x200>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
clocks {
diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c
index 96fa9b9..74bacb3 100644
--- a/arch/arm/mach-bcm2708/armctrl.c
+++ b/arch/arm/mach-bcm2708/armctrl.c
@@ -23,6 +23,8 @@
#include <linux/version.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
@@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct irq_data *d)
}
}
+#ifdef CONFIG_OF
+
+#define NR_IRQS_BANK0 21
+#define NR_BANKS 3
+#define IRQS_PER_BANK 32
+
+/* from drivers/irqchip/irq-bcm2835.c */
+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (WARN_ON(intsize != 2))
+ return -EINVAL;
+
+ if (WARN_ON(intspec[0] >= NR_BANKS))
+ return -EINVAL;
+
+ if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
+ return -EINVAL;
+
+ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
+ return -EINVAL;
+
+ if (intspec[0] == 0)
+ *out_hwirq = ARM_IRQ0_BASE + intspec[1];
+ else if (intspec[0] == 1)
+ *out_hwirq = ARM_IRQ1_BASE + intspec[1];
+ else
+ *out_hwirq = ARM_IRQ2_BASE + intspec[1];
+
+ /* reverse remap_irqs[] */
+ switch (*out_hwirq) {
+ case INTERRUPT_VC_JPEG:
+ *out_hwirq = INTERRUPT_JPEG;
+ break;
+ case INTERRUPT_VC_USB:
+ *out_hwirq = INTERRUPT_USB;
+ break;
+ case INTERRUPT_VC_3D:
+ *out_hwirq = INTERRUPT_3D;
+ break;
+ case INTERRUPT_VC_DMA2:
+ *out_hwirq = INTERRUPT_DMA2;
+ break;
+ case INTERRUPT_VC_DMA3:
+ *out_hwirq = INTERRUPT_DMA3;
+ break;
+ case INTERRUPT_VC_I2C:
+ *out_hwirq = INTERRUPT_I2C;
+ break;
+ case INTERRUPT_VC_SPI:
+ *out_hwirq = INTERRUPT_SPI;
+ break;
+ case INTERRUPT_VC_I2SPCM:
+ *out_hwirq = INTERRUPT_I2SPCM;
+ break;
+ case INTERRUPT_VC_SDIO:
+ *out_hwirq = INTERRUPT_SDIO;
+ break;
+ case INTERRUPT_VC_UART:
+ *out_hwirq = INTERRUPT_UART;
+ break;
+ case INTERRUPT_VC_ARASANSDIO:
+ *out_hwirq = INTERRUPT_ARASANSDIO;
+ break;
+ }
+
+ *out_type = IRQ_TYPE_NONE;
+ return 0;
+}
+
+static struct irq_domain_ops armctrl_ops = {
+ .xlate = armctrl_xlate
+};
+
+void __init armctrl_dt_init(void)
+{
+ struct device_node *np;
+ struct irq_domain *domain;
+
+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
+ if (!np)
+ return;
+
+ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
+ IRQ_ARMCTRL_START, 0,
+ &armctrl_ops, NULL);
+ WARN_ON(!domain);
+}
+#else
+void __init armctrl_dt_init(void) { }
+#endif /* CONFIG_OF */
+
#if defined(CONFIG_PM)
/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
@@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start,
armctrl_pm_register(base, irq_start, resume_sources);
init_FIQ(FIQ_START);
+ armctrl_dt_init();
return 0;
}
--
1.8.3.2

View file

@ -0,0 +1,82 @@
From fff70fcc73e09e86d46f87dd44459870f15423b2 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Thu, 10 Jul 2014 13:59:47 +0200
Subject: [PATCH 051/114] BCM2708: use pinctrl-bcm2835
Use pinctrl-bcm2835 instead of the pinctrl-bcm2708 and bcm2708_gpio
combination.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
---
arch/arm/boot/dts/bcm2708.dtsi | 12 ++++++++++++
arch/arm/mach-bcm2708/Kconfig | 3 +++
arch/arm/mach-bcm2708/bcm2708.c | 2 +-
drivers/pinctrl/pinctrl-bcm2835.c | 2 +-
4 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index a06f5b8..b2920c8 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -26,6 +26,18 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ gpio: gpio {
+ compatible = "brcm,bcm2835-gpio";
+ reg = <0x7e200000 0xb4>;
+ interrupts = <2 17>, <2 18>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
clocks {
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
index 182e7ba..4cfae55 100644
--- a/arch/arm/mach-bcm2708/Kconfig
+++ b/arch/arm/mach-bcm2708/Kconfig
@@ -14,6 +14,9 @@ config BCM2708_DT
depends on MACH_BCM2708
default n
select USE_OF
+ select ARCH_REQUIRE_GPIOLIB
+ select PINCTRL
+ select PINCTRL_BCM2835
help
Enable Device Tree support for BCM2708
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 747e27a..0e5bd43 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -767,7 +767,7 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2708_dmaman_device);
bcm_register_device(&bcm2708_vcio_device);
#ifdef CONFIG_BCM2708_GPIO
- bcm_register_device(&bcm2708_gpio_device);
+ bcm_register_device_dt(&bcm2708_gpio_device);
#endif
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
w1_gpio_pdata.pin = w1_gpio_pin;
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index eabba02..962e180 100644
--- a/drivers/pinctrl/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = {
.get = bcm2835_gpio_get,
.set = bcm2835_gpio_set,
.to_irq = bcm2835_gpio_to_irq,
- .base = -1,
+ .base = 0,
.ngpio = BCM2835_NUM_GPIOS,
.can_sleep = false,
};
--
1.8.3.2

View file

@ -0,0 +1,212 @@
From 5de6baef9b5d9e3a84e0c3752cfb7eaef2eb1a0f Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Sun, 27 Jul 2014 20:12:58 +0200
Subject: [PATCH 052/114] spi: bcm2708: add device tree support
Add DT support to driver and add to .dtsi file.
Setup pins and spidev in .dts file.
SPI is disabled by default.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
BCM2708: don't register SPI controller when using DT
The device for the SPI controller is in the Device Tree.
Only register the device when not using DT.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
spi: bcm2835: make driver available on ARCH_BCM2708
Make this driver available on ARCH_BCM2708
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
bcm2708: Remove the prohibition on mixing SPIDEV and DT
---
arch/arm/boot/dts/bcm2708-rpi-b.dts | 32 ++++++++++++++++++++++++++++++++
arch/arm/boot/dts/bcm2708.dtsi | 18 ++++++++++++++++++
arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++++++++++---
drivers/spi/Kconfig | 2 +-
drivers/spi/spi-bcm2708.c | 8 ++++++++
5 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index e319c8e..30107fb 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -5,4 +5,36 @@
/ {
compatible = "brcm,bcm2708";
model = "Raspberry Pi";
+
+ aliases {
+ spi0 = &spi0;
+ };
+};
+
+&gpio {
+ spi0_pins: spi0_pins {
+ brcm,pins = <7 8 9 10 11>;
+ brcm,function = <4>; /* alt0 */
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+
+ spidev@0{
+ compatible = "spidev";
+ reg = <0>; /* CE0 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <500000>;
+ };
+
+ spidev@1{
+ compatible = "spidev";
+ reg = <1>; /* CE1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <500000>;
+ };
};
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index b2920c8..e90bf4c 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -38,11 +38,29 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ spi0: spi@7e204000 {
+ compatible = "brcm,bcm2708-spi";
+ reg = <0x7e204000 0x1000>;
+ interrupts = <2 22>;
+ clocks = <&clk_spi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
+
+ clk_spi: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-output-names = "spi";
+ clock-frequency = <250000000>;
+ };
};
};
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 0e5bd43..a2069f8 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -486,6 +486,7 @@ static struct platform_device bcm2708_alsa_devices[] = {
},
};
+#ifndef CONFIG_OF
static struct resource bcm2708_spi_resources[] = {
{
.start = SPI0_BASE,
@@ -509,6 +510,7 @@ static struct platform_device bcm2708_spi_device = {
.dma_mask = &bcm2708_spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
};
+#endif
#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
@@ -670,6 +672,16 @@ int __init bcm_register_device(struct platform_device *pdev)
return ret;
}
+/*
+ * Use this macro for platform devices that are present in the Device Tree.
+ * This way the device is only added on non-DT builds.
+ */
+#ifdef CONFIG_OF
+#define bcm_register_device_dt(pdev)
+#else
+#define bcm_register_device_dt(pdev) bcm_register_device(pdev)
+#endif
+
int calc_rsts(int partition)
{
return PM_PASSWORD |
@@ -784,7 +796,7 @@ void __init bcm2708_init(void)
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
bcm_register_device(&bcm2708_alsa_devices[i]);
- bcm_register_device(&bcm2708_spi_device);
+ bcm_register_device_dt(&bcm2708_spi_device);
bcm_register_device(&bcm2708_bsc0_device);
bcm_register_device(&bcm2708_bsc1_device);
@@ -824,8 +836,9 @@ void __init bcm2708_init(void)
system_serial_low = serial;
#ifdef CONFIG_BCM2708_SPIDEV
- spi_register_board_info(bcm2708_spi_devices,
- ARRAY_SIZE(bcm2708_spi_devices));
+ if (!use_dt)
+ spi_register_board_info(bcm2708_spi_devices,
+ ARRAY_SIZE(bcm2708_spi_devices));
#endif
}
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 71b4741..a5238ab 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -77,7 +77,7 @@ config SPI_ATMEL
config SPI_BCM2835
tristate "BCM2835 SPI controller"
- depends on ARCH_BCM2835 || COMPILE_TEST
+ depends on ARCH_BCM2835 || ARCH_BCM2708 || COMPILE_TEST
help
This selects a driver for the Broadcom BCM2835 SPI master.
diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c
index 349d21f..041b5e2 100644
--- a/drivers/spi/spi-bcm2708.c
+++ b/drivers/spi/spi-bcm2708.c
@@ -512,6 +512,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev)
master->setup = bcm2708_spi_setup;
master->transfer = bcm2708_spi_transfer;
master->cleanup = bcm2708_spi_cleanup;
+ master->dev.of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, master);
bs = spi_master_get_devdata(master);
@@ -596,10 +597,17 @@ static int bcm2708_spi_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id bcm2708_spi_match[] = {
+ { .compatible = "brcm,bcm2708-spi", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, bcm2708_spi_match);
+
static struct platform_driver bcm2708_spi_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = bcm2708_spi_match,
},
.probe = bcm2708_spi_probe,
.remove = bcm2708_spi_remove,
--
1.8.3.2

View file

@ -0,0 +1,229 @@
From 772f3f8c0c321b2817d35f48d553db023ead2d90 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Tue, 29 Jul 2014 11:04:49 +0200
Subject: [PATCH 053/114] i2c: bcm2708: add device tree support
Add DT support to driver and add to .dtsi file.
Setup pins in .dts file.
i2c is disabled by default.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
bcm2708: don't register i2c controllers when using DT
The devices for the i2c controllers are in the Device Tree.
Only register devices when not using DT.
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
i2c: bcm2835: make driver available on ARCH_BCM2708
Make this driver available on ARCH_BCM2708
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
---
arch/arm/boot/dts/bcm2708-rpi-b.dts | 24 ++++++++++++++++++++++++
arch/arm/boot/dts/bcm2708.dtsi | 27 +++++++++++++++++++++++++++
arch/arm/mach-bcm2708/bcm2708.c | 6 ++++--
drivers/i2c/busses/Kconfig | 2 +-
drivers/i2c/busses/i2c-bcm2708.c | 24 ++++++++++++++++++++++++
5 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index 30107fb..5893122 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -8,6 +8,8 @@
aliases {
spi0 = &spi0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
};
};
@@ -16,6 +18,16 @@
brcm,pins = <7 8 9 10 11>;
brcm,function = <4>; /* alt0 */
};
+
+ i2c0_pins: i2c0 {
+ brcm,pins = <0 1>;
+ brcm,function = <4>;
+ };
+
+ i2c1_pins: i2c1 {
+ brcm,pins = <2 3>;
+ brcm,function = <4>;
+ };
};
&spi0 {
@@ -38,3 +50,15 @@
spi-max-frequency = <500000>;
};
};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+};
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index e90bf4c..2ca6d63 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -48,6 +48,26 @@
#size-cells = <0>;
status = "disabled";
};
+
+ i2c0: i2c@7e205000 {
+ compatible = "brcm,bcm2708-i2c";
+ reg = <0x7e205000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@7e804000 {
+ compatible = "brcm,bcm2708-i2c";
+ reg = <0x7e804000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
clocks {
@@ -55,6 +75,13 @@
#address-cells = <1>;
#size-cells = <0>;
+ clk_i2c: i2c {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <250000000>;
+ };
+
clk_spi: clock@2 {
compatible = "fixed-clock";
reg = <2>;
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index a2069f8..b45f327 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -532,6 +532,7 @@ static struct spi_board_info bcm2708_spi_devices[] = {
};
#endif
+#ifndef CONFIG_OF
static struct resource bcm2708_bsc0_resources[] = {
{
.start = BSC0_BASE,
@@ -570,6 +571,7 @@ static struct platform_device bcm2708_bsc1_device = {
.num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
.resource = bcm2708_bsc1_resources,
};
+#endif
static struct platform_device bcm2835_hwmon_device = {
.name = "bcm2835_hwmon",
@@ -797,8 +799,8 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2708_alsa_devices[i]);
bcm_register_device_dt(&bcm2708_spi_device);
- bcm_register_device(&bcm2708_bsc0_device);
- bcm_register_device(&bcm2708_bsc1_device);
+ bcm_register_device_dt(&bcm2708_bsc0_device);
+ bcm_register_device_dt(&bcm2708_bsc1_device);
bcm_register_device(&bcm2835_hwmon_device);
bcm_register_device(&bcm2835_thermal_device);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 3d3db41..d30a986 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -361,7 +361,7 @@ config I2C_AXXIA
config I2C_BCM2835
tristate "Broadcom BCM2835 I2C controller"
- depends on ARCH_BCM2835
+ depends on ARCH_BCM2835 || ARCH_BCM2708
help
If you say yes to this option, support will be included for the
BCM2835 I2C controller.
diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c
index 7d385a3..526129b 100644
--- a/drivers/i2c/busses/i2c-bcm2708.c
+++ b/drivers/i2c/busses/i2c-bcm2708.c
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
@@ -303,6 +304,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev)
unsigned long bus_hz;
u32 cdiv;
+ if (pdev->dev.of_node) {
+ u32 bus_clk_rate;
+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c");
+ if (pdev->id < 0) {
+ dev_err(&pdev->dev, "alias is missing\n");
+ return -EINVAL;
+ }
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "clock-frequency", &bus_clk_rate))
+ baudrate = bus_clk_rate;
+ else
+ dev_warn(&pdev->dev,
+ "Could not read clock-frequency property\n");
+ }
+
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "could not get IO memory\n");
@@ -336,6 +352,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev)
adap->dev.parent = &pdev->dev;
adap->nr = pdev->id;
strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
+ adap->dev.of_node = pdev->dev.of_node;
switch (pdev->id) {
case 0:
@@ -416,10 +433,17 @@ static int bcm2708_i2c_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id bcm2708_i2c_of_match[] = {
+ { .compatible = "brcm,bcm2708-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match);
+
static struct platform_driver bcm2708_i2c_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = bcm2708_i2c_of_match,
},
.probe = bcm2708_i2c_probe,
.remove = bcm2708_i2c_remove,
--
1.8.3.2

View file

@ -0,0 +1,41 @@
From 4c2238bfb5f0345f889d2f22d52601eb76f62eaf Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 14 Jul 2014 22:02:09 +0100
Subject: [PATCH 054/114] hid: Reduce default mouse polling interval to 60Hz
Reduces overhead when using X
---
drivers/hid/usbhid/hid-core.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ca6849a..4671921 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -49,7 +49,7 @@
* Module parameters.
*/
-static unsigned int hid_mousepoll_interval;
+static unsigned int hid_mousepoll_interval = ~0;
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
@@ -1079,8 +1079,12 @@ static int usbhid_start(struct hid_device *hid)
}
/* Change the polling interval of mice. */
- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
- interval = hid_mousepoll_interval;
+ if (hid->collection->usage == HID_GD_MOUSE) {
+ if (hid_mousepoll_interval == ~0 && interval < 16)
+ interval = 16;
+ else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0)
+ interval = hid_mousepoll_interval;
+ }
ret = -ENOMEM;
if (usb_endpoint_dir_in(endpoint)) {
--
1.8.3.2

View file

@ -0,0 +1,26 @@
From 19e17e411eb8eb971ee963f083ec8446dcd0538e Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Thu, 24 Jul 2014 21:24:03 +0100
Subject: [PATCH 055/114] usb: core: make overcurrent messages more prominent
Hub overcurrent messages are more serious than "debug". Increase loglevel.
---
drivers/usb/core/hub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b649fef..5f8d914 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4923,7 +4923,7 @@ static void port_event(struct usb_hub *hub, int port1)
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
u16 status = 0, unused;
- dev_dbg(&port_dev->dev, "over-current change\n");
+ dev_notice(&port_dev->dev, "over-current change\n");
usb_clear_port_feature(hdev, port1,
USB_PORT_FEAT_C_OVER_CURRENT);
msleep(100); /* Cool down */
--
1.8.3.2

View file

@ -0,0 +1,57 @@
From 48c48c4437603bad79eb848ac03b21a86cc3bb90 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Thu, 7 Aug 2014 02:03:50 +0100
Subject: [PATCH 057/114] Revert "ARM: dma: Use dma_pfn_offset for dma address
translation"
This reverts commit 6ce0d20016925d031f1e24d64302e4c976d7cec6.
---
arch/arm/include/asm/dma-mapping.h | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 85738b2..9477f09 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -58,37 +58,21 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
#ifndef __arch_pfn_to_dma
static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{
- if (dev)
- pfn -= dev->dma_pfn_offset;
return (dma_addr_t)__pfn_to_bus(pfn);
}
static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{
- unsigned long pfn = __bus_to_pfn(addr);
-
- if (dev)
- pfn += dev->dma_pfn_offset;
-
- return pfn;
+ return __bus_to_pfn(addr);
}
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
{
- if (dev) {
- unsigned long pfn = dma_to_pfn(dev, addr);
-
- return phys_to_virt(__pfn_to_phys(pfn));
- }
-
return (void *)__bus_to_virt((unsigned long)addr);
}
static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
{
- if (dev)
- return pfn_to_dma(dev, virt_to_pfn(addr));
-
return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
}
--
1.8.3.2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
From 06c752756a452a0c59447836edce57ef7393be5c Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Tue, 13 Jan 2015 17:12:18 +0000
Subject: [PATCH 059/114] mmc: Disable CMD23 transfers on all cards
Pending wire-level investigation of these types of transfers
and associated errors on bcm2835-mmc, disable for now. Fallback of
CMD18/CMD25 transfers will be used automatically by the MMC layer.
Reported/Tested-by: Gellert Weisz <gellert@raspberrypi.org>
---
drivers/mmc/core/quirks.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c
index dd1d1e0..f472082 100644
--- a/drivers/mmc/core/quirks.c
+++ b/drivers/mmc/core/quirks.c
@@ -95,5 +95,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table)
f->vendor_fixup(card, f->data);
}
}
+ /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail.
+ * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers).
+ */
+ card->quirks |= MMC_QUIRK_BLK_NO_CMD23;
}
EXPORT_SYMBOL(mmc_fixup_device);
--
1.8.3.2

View file

@ -0,0 +1,229 @@
From fb7a1cc51aee2d66232d3a170e1343dfbb7b3485 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 10:06:56 +0200
Subject: [PATCH 060/114] Added support for HiFiBerry DAC+
The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses
a different codec chip (PCM5122), therefore a new driver is necessary.
---
arch/arm/configs/bcmrpi_defconfig | 1 +
arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++
sound/soc/bcm/Kconfig | 7 +++
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/hifiberry_dacplus.c | 119 ++++++++++++++++++++++++++++++++++++++
5 files changed, 148 insertions(+)
create mode 100644 sound/soc/bcm/hifiberry_dacplus.c
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index c363a10..28547eb 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m
CONFIG_SND_SOC=m
CONFIG_SND_BCM2708_SOC_I2S=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 5ff1299..aa62e55 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -645,6 +645,20 @@ static struct platform_device snd_pcm5102a_codec_device = {
};
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE)
+static struct platform_device snd_rpi_hifiberry_dacplus_device = {
+ .name = "snd-rpi-hifiberry-dacplus",
+ .id = 0,
+ .num_resources = 0,
+};
+
+static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcm5122", 0x4d)
+ },
+};
+#endif
+
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
static struct platform_device snd_hifiberry_digi_device = {
.name = "snd-hifiberry-digi",
@@ -845,6 +859,11 @@ void __init bcm2708_init(void)
bcm_register_device(&snd_pcm5102a_codec_device);
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE)
+ bcm_register_device(&snd_rpi_hifiberry_dacplus_device);
+ i2c_register_board_info(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices));
+#endif
+
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
bcm_register_device(&snd_hifiberry_digi_device);
i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index c621a5e..926a82b 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC
help
Say Y or M if you want to add support for HifiBerry DAC.
+config SND_BCM2708_SOC_HIFIBERRY_DACPLUS
+ tristate "Support for HifiBerry DAC+"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_PCM512x
+ help
+ Say Y or M if you want to add support for HifiBerry DAC+.
+
config SND_BCM2708_SOC_HIFIBERRY_DIGI
tristate "Support for HifiBerry Digi"
depends on SND_BCM2708_SOC_I2S
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index d597fb0..c02e3a2 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -10,11 +10,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
# BCM2708 Machine Support
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
+snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c
new file mode 100644
index 0000000..c63387b
--- /dev/null
+++ b/sound/soc/bcm/hifiberry_dacplus.c
@@ -0,0 +1,119 @@
+/*
+ * ASoC Driver for HiFiBerry DAC+
+ *
+ * Author: Daniel Matuschek
+ * Copyright 2014
+ * based on code by Florian Meier <florian.meier@koalo.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+#include "../codecs/pcm512x.h"
+
+static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08);
+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02);
+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
+ return 0;
+}
+
+static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
+}
+
+static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
+ return 0;
+}
+
+static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = {
+ .hw_params = snd_rpi_hifiberry_dacplus_hw_params,
+ .startup = snd_rpi_hifiberry_dacplus_startup,
+ .shutdown = snd_rpi_hifiberry_dacplus_shutdown,
+};
+
+static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = {
+{
+ .name = "HiFiBerry DAC+",
+ .stream_name = "HiFiBerry DAC+ HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "pcm512x-hifi",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "pcm512x.1-004d",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &snd_rpi_hifiberry_dacplus_ops,
+ .init = snd_rpi_hifiberry_dacplus_init,
+},
+};
+
+/* audio machine driver */
+static struct snd_soc_card snd_rpi_hifiberry_dacplus = {
+ .name = "snd_rpi_hifiberry_dacplus",
+ .dai_link = snd_rpi_hifiberry_dacplus_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai),
+};
+
+static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
+ if (ret)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus);
+}
+
+static struct platform_driver snd_rpi_hifiberry_dacplus_driver = {
+ .driver = {
+ .name = "snd-rpi-hifiberry-dacplus",
+ .owner = THIS_MODULE,
+ },
+ .probe = snd_rpi_hifiberry_dacplus_probe,
+ .remove = snd_rpi_hifiberry_dacplus_remove,
+};
+
+module_platform_driver(snd_rpi_hifiberry_dacplus_driver);
+
+MODULE_AUTHOR("Daniel Matuschek <daniel@hifiberry.com>");
+MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+");
+MODULE_LICENSE("GPL v2");
--
1.8.3.2

View file

@ -0,0 +1,849 @@
From 709288ac793d8a070f33c36e76ca03281fa6b417 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 11:09:58 +0200
Subject: [PATCH 061/114] Added driver for HiFiBerry Amp amplifier add-on board
The driver contains a low-level hardware driver for the TAS5713 and the
drivers for the Raspberry Pi I2S subsystem.
---
arch/arm/configs/bcmrpi_defconfig | 1 +
arch/arm/mach-bcm2708/bcm2708.c | 20 +++
sound/soc/bcm/Kconfig | 7 +
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/hifiberry_amp.c | 106 +++++++++++
sound/soc/codecs/Kconfig | 4 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/tas5713.c | 362 ++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/tas5713.h | 210 ++++++++++++++++++++++
9 files changed, 714 insertions(+)
create mode 100644 sound/soc/bcm/hifiberry_amp.c
create mode 100644 sound/soc/codecs/tas5713.c
create mode 100644 sound/soc/codecs/tas5713.h
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 28547eb..997e1f3 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -758,6 +758,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
CONFIG_SND_BCM2708_SOC_RPI_DAC=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
CONFIG_SND_SIMPLE_CARD=m
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index aa62e55..5f6a1fa 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -674,6 +674,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = {
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE)
+static struct platform_device snd_hifiberry_amp_device = {
+ .name = "snd-hifiberry-amp",
+ .id = 0,
+ .num_resources = 0,
+};
+
+static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tas5713", 0x1b)
+ },
+};
+#endif
+
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
static struct platform_device snd_rpi_dac_device = {
.name = "snd-rpi-dac",
@@ -869,6 +883,12 @@ void __init bcm2708_init(void)
i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
#endif
+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE)
+ bcm_register_device(&snd_hifiberry_amp_device);
+ i2c_register_board_info(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices));
+#endif
+
+
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
bcm_register_device(&snd_rpi_dac_device);
bcm_register_device(&snd_pcm1794a_codec_device);
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 926a82b..a562ddf 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -40,6 +40,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI
help
Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board.
+config SND_BCM2708_SOC_HIFIBERRY_AMP
+ tristate "Support for the HifiBerry Amp"
+ depends on SND_BCM2708_SOC_I2S
+ select SND_SOC_TAS5713
+ help
+ Say Y or M if you want to add support for the HifiBerry Amp amplifier board.
+
config SND_BCM2708_SOC_RPI_DAC
tristate "Support for RPi-DAC"
depends on SND_BCM2708_SOC_I2S
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index c02e3a2..17ea2b0 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
+snd-soc-hifiberry-amp-objs := hifiberry_amp.o
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c
new file mode 100644
index 0000000..1e87ee0
--- /dev/null
+++ b/sound/soc/bcm/hifiberry_amp.c
@@ -0,0 +1,106 @@
+/*
+ * ASoC Driver for HifiBerry AMP
+ *
+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
+ * Copyright 2014
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd)
+{
+ // ToDo: init of the dsp-registers.
+ return 0;
+}
+
+static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params )
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
+}
+
+static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = {
+ .hw_params = snd_rpi_hifiberry_amp_hw_params,
+};
+
+static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = {
+ {
+ .name = "HifiBerry AMP",
+ .stream_name = "HifiBerry AMP HiFi",
+ .cpu_dai_name = "bcm2708-i2s.0",
+ .codec_dai_name = "tas5713-hifi",
+ .platform_name = "bcm2708-i2s.0",
+ .codec_name = "tas5713.1-001b",
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &snd_rpi_hifiberry_amp_ops,
+ .init = snd_rpi_hifiberry_amp_init,
+ },
+};
+
+
+static struct snd_soc_card snd_rpi_hifiberry_amp = {
+ .name = "snd_rpi_hifiberry_amp",
+ .dai_link = snd_rpi_hifiberry_amp_dai,
+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai),
+};
+
+
+static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ snd_rpi_hifiberry_amp.dev = &pdev->dev;
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp);
+
+ if (ret != 0) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+ }
+
+ return ret;
+}
+
+
+static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev)
+{
+ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp);
+}
+
+
+static struct platform_driver snd_rpi_hifiberry_amp_driver = {
+ .driver = {
+ .name = "snd-hifiberry-amp",
+ .owner = THIS_MODULE,
+ },
+ .probe = snd_rpi_hifiberry_amp_probe,
+ .remove = snd_rpi_hifiberry_amp_remove,
+};
+
+
+module_platform_driver(snd_rpi_hifiberry_amp_driver);
+
+
+MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
+MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3c236a6..83c55f8 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -105,6 +105,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TAS5086 if I2C
select SND_SOC_TLV320AIC23_I2C if I2C
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
+ select SND_SOC_TAS5713 if I2C
select SND_SOC_TLV320AIC26 if SPI_MASTER
select SND_SOC_TLV320AIC31XX if I2C
select SND_SOC_TLV320AIC32X4 if I2C
@@ -585,6 +586,9 @@ config SND_SOC_TAS5086
tristate "Texas Instruments TAS5086 speaker amplifier"
depends on I2C
+config SND_SOC_TAS5713
+ tristate
+
config SND_SOC_TLV320AIC23
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 2a7f823..ca76a2b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -103,6 +103,7 @@ snd-soc-sta350-objs := sta350.o
snd-soc-sta529-objs := sta529.o
snd-soc-stac9766-objs := stac9766.o
snd-soc-tas5086-objs := tas5086.o
+snd-soc-tas5713-objs := tas5713.o
snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
@@ -278,6 +279,7 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
+obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c
new file mode 100644
index 0000000..a24c1da
--- /dev/null
+++ b/sound/soc/codecs/tas5713.c
@@ -0,0 +1,362 @@
+/*
+ * ASoC Driver for TAS5713
+ *
+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
+ * Copyright 2014
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+
+#include "tas5713.h"
+
+
+static struct i2c_client *i2c;
+
+struct tas5713_priv {
+ struct regmap *regmap;
+ int mclk_div;
+ struct snd_soc_codec *codec;
+};
+
+static struct tas5713_priv *priv_data;
+
+
+
+
+/*
+ * _ _ ___ _ ___ _ _
+ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___
+ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-<
+ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/
+ *
+ */
+
+static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1);
+
+
+static const struct snd_kcontrol_new tas5713_snd_controls[] = {
+ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv),
+ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv)
+};
+
+
+
+
+/*
+ * __ __ _ _ ___ _
+ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _
+ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_|
+ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_|
+ *
+ */
+
+static int tas5713_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ u16 blen = 0x00;
+
+ struct snd_soc_codec *codec;
+ codec = dai->codec;
+ priv_data->codec = dai->codec;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ blen = 0x03;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ blen = 0x1;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ blen = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ blen = 0x05;
+ break;
+ default:
+ dev_err(dai->dev, "Unsupported word length: %u\n",
+ params_format(params));
+ return -EINVAL;
+ }
+
+ // set word length
+ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen);
+
+ return 0;
+}
+
+
+static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
+{
+ unsigned int val = 0;
+
+ struct tas5713_priv *tas5713;
+ struct snd_soc_codec *codec = dai->codec;
+ tas5713 = snd_soc_codec_get_drvdata(codec);
+
+ if (mute) {
+ val = TAS5713_SOFT_MUTE_ALL;
+ }
+
+ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val);
+}
+
+
+static const struct snd_soc_dai_ops tas5713_dai_ops = {
+ .hw_params = tas5713_hw_params,
+ .mute_stream = tas5713_mute_stream,
+};
+
+
+static struct snd_soc_dai_driver tas5713_dai = {
+ .name = "tas5713-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ),
+ },
+ .ops = &tas5713_dai_ops,
+};
+
+
+
+
+/*
+ * ___ _ ___ _
+ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _
+ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_|
+ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_|
+ *
+ */
+
+static int tas5713_remove(struct snd_soc_codec *codec)
+{
+ struct tas5713_priv *tas5713;
+
+ tas5713 = snd_soc_codec_get_drvdata(codec);
+
+ return 0;
+}
+
+
+static int tas5713_probe(struct snd_soc_codec *codec)
+{
+ struct tas5713_priv *tas5713;
+ int i, ret;
+
+ i2c = container_of(codec->dev, struct i2c_client, dev);
+
+ tas5713 = snd_soc_codec_get_drvdata(codec);
+
+ // Reset error
+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
+
+ // Trim oscillator
+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00);
+ msleep(1000);
+
+ // Reset error
+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
+
+ // Clock mode: 44/48kHz, MCLK=64xfs
+ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60);
+
+ // I2S 24bit
+ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05);
+
+ // Unmute
+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
+ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00);
+
+ // Set volume to 0db
+ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00);
+
+ // Now start programming the default initialization sequence
+ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) {
+ ret = i2c_master_send(i2c,
+ tas5713_init_sequence[i].data,
+ tas5713_init_sequence[i].size);
+
+ if (ret < 0) {
+ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret);
+ }
+ }
+
+ // Unmute
+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
+
+
+ return 0;
+}
+
+
+static struct snd_soc_codec_driver soc_codec_dev_tas5713 = {
+ .probe = tas5713_probe,
+ .remove = tas5713_remove,
+ .controls = tas5713_snd_controls,
+ .num_controls = ARRAY_SIZE(tas5713_snd_controls),
+};
+
+
+
+
+/*
+ * ___ ___ ___ ___ _
+ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _
+ * | | / / (__ | |) | '_| \ V / -_) '_|
+ * |___/___\___| |___/|_| |_|\_/\___|_|
+ *
+ */
+
+static const struct reg_default tas5713_reg_defaults[] = {
+ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB
+ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB
+ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB
+ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB
+};
+
+
+static bool tas5713_reg_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TAS5713_DEVICE_ID:
+ case TAS5713_ERROR_STATUS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+static const struct of_device_id tas5713_of_match[] = {
+ { .compatible = "ti,tas5713", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tas5713_of_match);
+
+
+static struct regmap_config tas5713_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = TAS5713_MAX_REGISTER,
+ .volatile_reg = tas5713_reg_volatile,
+
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = tas5713_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults),
+};
+
+
+static int tas5713_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ int ret;
+
+ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL);
+ if (!priv_data)
+ return -ENOMEM;
+
+ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config);
+ if (IS_ERR(priv_data->regmap)) {
+ ret = PTR_ERR(priv_data->regmap);
+ return ret;
+ }
+
+ i2c_set_clientdata(i2c, priv_data);
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_tas5713, &tas5713_dai, 1);
+
+ return ret;
+}
+
+
+static int tas5713_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_codec(&i2c->dev);
+ i2c_set_clientdata(i2c, NULL);
+
+ kfree(priv_data);
+
+ return 0;
+}
+
+
+static const struct i2c_device_id tas5713_i2c_id[] = {
+ { "tas5713", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id);
+
+
+static struct i2c_driver tas5713_i2c_driver = {
+ .driver = {
+ .name = "tas5713",
+ .owner = THIS_MODULE,
+ .of_match_table = tas5713_of_match,
+ },
+ .probe = tas5713_i2c_probe,
+ .remove = tas5713_i2c_remove,
+ .id_table = tas5713_i2c_id
+};
+
+
+static int __init tas5713_modinit(void)
+{
+ int ret = 0;
+
+ ret = i2c_add_driver(&tas5713_i2c_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n",
+ ret);
+ }
+
+ return ret;
+}
+module_init(tas5713_modinit);
+
+
+static void __exit tas5713_exit(void)
+{
+ i2c_del_driver(&tas5713_i2c_driver);
+}
+module_exit(tas5713_exit);
+
+
+MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
+MODULE_DESCRIPTION("ASoC driver for TAS5713");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tas5713.h b/sound/soc/codecs/tas5713.h
new file mode 100644
index 0000000..8f019e0
--- /dev/null
+++ b/sound/soc/codecs/tas5713.h
@@ -0,0 +1,210 @@
+/*
+ * ASoC Driver for TAS5713
+ *
+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
+ * Copyright 2014
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef _TAS5713_H
+#define _TAS5713_H
+
+
+// TAS5713 I2C-bus register addresses
+
+#define TAS5713_CLOCK_CTRL 0x00
+#define TAS5713_DEVICE_ID 0x01
+#define TAS5713_ERROR_STATUS 0x02
+#define TAS5713_SYSTEM_CTRL1 0x03
+#define TAS5713_SERIAL_DATA_INTERFACE 0x04
+#define TAS5713_SYSTEM_CTRL2 0x05
+#define TAS5713_SOFT_MUTE 0x06
+#define TAS5713_VOL_MASTER 0x07
+#define TAS5713_VOL_CH1 0x08
+#define TAS5713_VOL_CH2 0x09
+#define TAS5713_VOL_HEADPHONE 0x0A
+#define TAS5713_VOL_CONFIG 0x0E
+#define TAS5713_MODULATION_LIMIT 0x10
+#define TAS5713_IC_DLY_CH1 0x11
+#define TAS5713_IC_DLY_CH2 0x12
+#define TAS5713_IC_DLY_CH3 0x13
+#define TAS5713_IC_DLY_CH4 0x14
+
+#define TAS5713_START_STOP_PERIOD 0x1A
+#define TAS5713_OSC_TRIM 0x1B
+#define TAS5713_BKND_ERR 0x1C
+
+#define TAS5713_INPUT_MUX 0x20
+#define TAS5713_SRC_SELECT_CH4 0x21
+#define TAS5713_PWM_MUX 0x25
+
+#define TAS5713_CH1_BQ0 0x29
+#define TAS5713_CH1_BQ1 0x2A
+#define TAS5713_CH1_BQ2 0x2B
+#define TAS5713_CH1_BQ3 0x2C
+#define TAS5713_CH1_BQ4 0x2D
+#define TAS5713_CH1_BQ5 0x2E
+#define TAS5713_CH1_BQ6 0x2F
+#define TAS5713_CH1_BQ7 0x58
+#define TAS5713_CH1_BQ8 0x59
+
+#define TAS5713_CH2_BQ0 0x30
+#define TAS5713_CH2_BQ1 0x31
+#define TAS5713_CH2_BQ2 0x32
+#define TAS5713_CH2_BQ3 0x33
+#define TAS5713_CH2_BQ4 0x34
+#define TAS5713_CH2_BQ5 0x35
+#define TAS5713_CH2_BQ6 0x36
+#define TAS5713_CH2_BQ7 0x5C
+#define TAS5713_CH2_BQ8 0x5D
+
+#define TAS5713_CH4_BQ0 0x5A
+#define TAS5713_CH4_BQ1 0x5B
+#define TAS5713_CH3_BQ0 0x5E
+#define TAS5713_CH3_BQ1 0x5F
+
+#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B
+#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C
+#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E
+#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F
+#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40
+#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43
+#define TAS5713_DRC_CTRL 0x46
+
+#define TAS5713_BANK_SW_CTRL 0x50
+#define TAS5713_CH1_OUTPUT_MIXER 0x51
+#define TAS5713_CH2_OUTPUT_MIXER 0x52
+#define TAS5713_CH1_INPUT_MIXER 0x53
+#define TAS5713_CH2_INPUT_MIXER 0x54
+#define TAS5713_OUTPUT_POST_SCALE 0x56
+#define TAS5713_OUTPUT_PRESCALE 0x57
+
+#define TAS5713_IDF_POST_SCALE 0x62
+
+#define TAS5713_CH1_INLINE_MIXER 0x70
+#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71
+#define TAS5713_CH1_R_CHANNEL_MIXER 0x72
+#define TAS5713_CH1_L_CHANNEL_MIXER 0x73
+#define TAS5713_CH2_INLINE_MIXER 0x74
+#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75
+#define TAS5713_CH2_L_CHANNEL_MIXER 0x76
+#define TAS5713_CH2_R_CHANNEL_MIXER 0x77
+
+#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8
+#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9
+
+#define TAS5713_REGISTER_COUNT 0x46
+#define TAS5713_MAX_REGISTER 0xF9
+
+
+// Bitmasks for registers
+#define TAS5713_SOFT_MUTE_ALL 0x07
+
+
+
+struct tas5713_init_command {
+ const int size;
+ const char *const data;
+};
+
+static const struct tas5713_init_command tas5713_init_sequence[] = {
+
+ // Trim oscillator
+ { .size = 2, .data = "\x1B\x00" },
+ // System control register 1 (0x03): block DC
+ { .size = 2, .data = "\x03\x80" },
+ // Mute everything
+ { .size = 2, .data = "\x05\x40" },
+ // Modulation limit register (0x10): 97.7%
+ { .size = 2, .data = "\x10\x02" },
+ // Interchannel delay registers
+ // (0x11, 0x12, 0x13, and 0x14): BD mode
+ { .size = 2, .data = "\x11\xB8" },
+ { .size = 2, .data = "\x12\x60" },
+ { .size = 2, .data = "\x13\xA0" },
+ { .size = 2, .data = "\x14\x48" },
+ // PWM shutdown group register (0x19): no shutdown
+ { .size = 2, .data = "\x19\x00" },
+ // Input multiplexer register (0x20): BD mode
+ { .size = 2, .data = "\x20\x00\x89\x77\x72" },
+ // PWM output mux register (0x25)
+ // Channel 1 --> OUTA, channel 1 neg --> OUTB
+ // Channel 2 --> OUTC, channel 2 neg --> OUTD
+ { .size = 5, .data = "\x25\x01\x02\x13\x45" },
+ // DRC control (0x46): DRC off
+ { .size = 5, .data = "\x46\x00\x00\x00\x00" },
+ // BKND_ERR register (0x1C): 299ms reset period
+ { .size = 2, .data = "\x1C\x07" },
+ // Mute channel 3
+ { .size = 2, .data = "\x0A\xFF" },
+ // Volume configuration register (0x0E): volume slew 512 steps
+ { .size = 2, .data = "\x0E\x90" },
+ // Clock control register (0x00): 44/48kHz, MCLK=64xfs
+ { .size = 2, .data = "\x00\x60" },
+ // Bank switch and eq control (0x50): no bank switching
+ { .size = 5, .data = "\x50\x00\x00\x00\x00" },
+ // Volume registers (0x07, 0x08, 0x09, 0x0A)
+ { .size = 2, .data = "\x07\x20" },
+ { .size = 2, .data = "\x08\x30" },
+ { .size = 2, .data = "\x09\x30" },
+ { .size = 2, .data = "\x0A\xFF" },
+ // 0x72, 0x73, 0x76, 0x77 input mixer:
+ // no intermix between channels
+ { .size = 5, .data = "\x72\x00\x00\x00\x00" },
+ { .size = 5, .data = "\x73\x00\x80\x00\x00" },
+ { .size = 5, .data = "\x76\x00\x00\x00\x00" },
+ { .size = 5, .data = "\x77\x00\x80\x00\x00" },
+ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer:
+ // no inline DRC inmix
+ { .size = 5, .data = "\x70\x00\x80\x00\x00" },
+ { .size = 5, .data = "\x71\x00\x00\x00\x00" },
+ { .size = 5, .data = "\x74\x00\x80\x00\x00" },
+ { .size = 5, .data = "\x75\x00\x00\x00\x00" },
+ // 0x56, 0x57 Output scale
+ { .size = 5, .data = "\x56\x00\x80\x00\x00" },
+ { .size = 5, .data = "\x57\x00\x02\x00\x00" },
+ // 0x3B, 0x3c
+ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" },
+ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
+ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" },
+ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
+ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
+ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
+ // 0x51, 0x52: output mixer
+ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" },
+ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" },
+ // PEQ defaults
+ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
+};
+
+
+#endif /* _TAS5713_H */
--
1.8.3.2

View file

@ -0,0 +1,461 @@
From 37fd085e3449fabd2d976d671ebf2a6c631c9afd Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 1 Sep 2014 16:35:56 +0100
Subject: [PATCH 063/114] bcm2708: Allow option card devices to be configured
via DT
If the kernel is built with Device Tree support, and if a DT blob
is provided for the kernel at boot time, then the platform devices
for option cards are not created. This avoids both the need to
blacklist unwanted devices, and the need to update the board
support code with each new device.
---
arch/arm/mach-bcm2708/bcm2708.c | 70 ++++++++++++++++++++---------------------
drivers/dma/bcm2708-dmaengine.c | 14 ++++-----
drivers/mmc/host/bcm2835-mmc.c | 24 +++++++-------
drivers/of/fdt.c | 6 +++-
sound/soc/bcm/bcm2708-i2s.c | 29 +++++++++++------
sound/soc/bcm/bcm2835-i2s.c | 1 +
6 files changed, 80 insertions(+), 64 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 5f6a1fa..2c6a29d 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/spi/spi.h>
+#include <linux/gpio/machine.h>
#include <linux/w1-gpio.h>
#include <linux/version.h>
@@ -93,6 +94,8 @@ static unsigned reboot_part = 0;
static unsigned w1_gpio_pin = W1_GPIO;
static unsigned w1_gpio_pullup = W1_PULLUP;
+static unsigned use_dt = 0;
+
static void __init bcm2708_init_led(void);
void __init bcm2708_init_irq(void)
@@ -514,7 +517,6 @@ static struct platform_device bcm2708_alsa_devices[] = {
},
};
-#ifndef CONFIG_OF
static struct resource bcm2708_spi_resources[] = {
{
.start = SPI0_BASE,
@@ -538,7 +540,6 @@ static struct platform_device bcm2708_spi_device = {
.dma_mask = &bcm2708_spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
};
-#endif
#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
@@ -560,7 +561,6 @@ static struct spi_board_info bcm2708_spi_devices[] = {
};
#endif
-#ifndef CONFIG_OF
static struct resource bcm2708_bsc0_resources[] = {
{
.start = BSC0_BASE,
@@ -599,7 +599,6 @@ static struct platform_device bcm2708_bsc1_device = {
.num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
.resource = bcm2708_bsc1_resources,
};
-#endif
static struct platform_device bcm2835_hwmon_device = {
.name = "bcm2835_hwmon",
@@ -609,7 +608,7 @@ static struct platform_device bcm2835_thermal_device = {
.name = "bcm2835_thermal",
};
-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE)
static struct resource bcm2708_i2s_resources[] = {
{
.start = I2S_BASE,
@@ -731,14 +730,14 @@ int __init bcm_register_device(struct platform_device *pdev)
}
/*
- * Use this macro for platform devices that are present in the Device Tree.
- * This way the device is only added on non-DT builds.
+ * Use these macros for platform and i2c devices that are present in the
+ * Device Tree. This way the devices are only added on non-DT systems.
*/
-#ifdef CONFIG_OF
-#define bcm_register_device_dt(pdev)
-#else
-#define bcm_register_device_dt(pdev) bcm_register_device(pdev)
-#endif
+#define bcm_register_device_dt(pdev) \
+ if (!use_dt) bcm_register_device(pdev)
+
+#define i2c_register_board_info_dt(busnum, info, n) \
+ if (!use_dt) i2c_register_board_info(busnum, info, n)
int calc_rsts(int partition)
{
@@ -814,7 +813,9 @@ static void __init bcm2708_dt_init(void)
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
if (ret) {
pr_err("of_platform_populate failed: %d\n", ret);
- BUG();
+ /* Proceed as if CONFIG_OF was not defined */
+ } else {
+ use_dt = 1;
}
}
#else
@@ -842,7 +843,7 @@ void __init bcm2708_init(void)
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
w1_gpio_pdata.pin = w1_gpio_pin;
w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
- platform_device_register(&w1_device);
+ bcm_register_device_dt(&w1_device);
#endif
bcm_register_device(&bcm2708_systemtimer_device);
bcm_register_device(&bcm2708_fb_device);
@@ -857,46 +858,45 @@ void __init bcm2708_init(void)
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
bcm_register_device(&bcm2708_alsa_devices[i]);
+ bcm_register_device(&bcm2835_hwmon_device);
+ bcm_register_device(&bcm2835_thermal_device);
+
bcm_register_device_dt(&bcm2708_spi_device);
bcm_register_device_dt(&bcm2708_bsc0_device);
bcm_register_device_dt(&bcm2708_bsc1_device);
- bcm_register_device(&bcm2835_hwmon_device);
- bcm_register_device(&bcm2835_thermal_device);
-
-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
- bcm_register_device(&bcm2708_i2s_device);
+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE)
+ bcm_register_device_dt(&bcm2708_i2s_device);
#endif
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE)
- bcm_register_device(&snd_hifiberry_dac_device);
- bcm_register_device(&snd_pcm5102a_codec_device);
+ bcm_register_device_dt(&snd_hifiberry_dac_device);
+ bcm_register_device_dt(&snd_pcm5102a_codec_device);
#endif
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE)
- bcm_register_device(&snd_rpi_hifiberry_dacplus_device);
- i2c_register_board_info(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices));
+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device);
+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices));
#endif
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
- bcm_register_device(&snd_hifiberry_digi_device);
- i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
+ bcm_register_device_dt(&snd_hifiberry_digi_device);
+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
#endif
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE)
- bcm_register_device(&snd_hifiberry_amp_device);
- i2c_register_board_info(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices));
+ bcm_register_device_dt(&snd_hifiberry_amp_device);
+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices));
#endif
-
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
- bcm_register_device(&snd_rpi_dac_device);
- bcm_register_device(&snd_pcm1794a_codec_device);
+ bcm_register_device_dt(&snd_rpi_dac_device);
+ bcm_register_device_dt(&snd_pcm1794a_codec_device);
#endif
#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
- bcm_register_device(&snd_rpi_iqaudio_dac_device);
- i2c_register_board_info(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device);
+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
#endif
@@ -1041,9 +1041,9 @@ static struct platform_device bcm2708_led_device = {
static void __init bcm2708_init_led(void)
{
- bcm2708_leds[0].gpio = disk_led_gpio;
- bcm2708_leds[0].active_low = disk_led_active_low;
- platform_device_register(&bcm2708_led_device);
+ bcm2708_leds[0].gpio = disk_led_gpio;
+ bcm2708_leds[0].active_low = disk_led_active_low;
+ bcm_register_device_dt(&bcm2708_led_device);
}
#else
static inline void bcm2708_init_led(void)
diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c
index 10463db..3f9be02 100644
--- a/drivers/dma/bcm2708-dmaengine.c
+++ b/drivers/dma/bcm2708-dmaengine.c
@@ -42,7 +42,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
/* dma manager */
#include <mach/dma.h>
@@ -721,7 +721,7 @@ static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
}
}
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq)
{
struct bcm2835_chan *c;
@@ -784,7 +784,7 @@ static const struct of_device_id bcm2835_dma_of_match[] = {
};
MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
struct of_dma *ofdma)
{
@@ -817,7 +817,7 @@ static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan,
static int bcm2835_dma_probe(struct platform_device *pdev)
{
struct bcm2835_dmadev *od;
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
struct resource *res;
void __iomem *base;
uint32_t chans_available;
@@ -830,10 +830,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- /* If CONFIG_OF is selected, device tree is used */
+ /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */
/* hence the difference between probing */
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
@@ -987,7 +987,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev)
return 0;
}
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
static struct platform_driver bcm2835_dma_driver = {
diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c
index cefba7c..34d6167 100644
--- a/drivers/mmc/host/bcm2835-mmc.c
+++ b/drivers/mmc/host/bcm2835-mmc.c
@@ -42,7 +42,7 @@
#include "sdhci.h"
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
#define BCM2835_CLOCK_FREQ 250000000
#endif
@@ -662,7 +662,7 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd
}
timeout = jiffies;
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
if (!cmd->data && cmd->busy_timeout > 9000)
timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ;
else
@@ -962,7 +962,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id)
struct bcm2835_host *host = dev_id;
u32 intmask, mask, unexpected = 0;
int max_loops = 16;
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
int cardint = 0;
#endif
@@ -993,7 +993,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id)
mmc_hostname(host->mmc));
if (intmask & SDHCI_INT_CARD_INT) {
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
cardint = 1;
#else
bcm2835_mmc_enable_sdio_irq_nolock(host, false);
@@ -1026,7 +1026,7 @@ out:
bcm2835_mmc_dumpregs(host);
}
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
if (cardint)
mmc_signal_sdio_irq(host->mmc);
#endif
@@ -1034,7 +1034,7 @@ out:
return result;
}
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id)
{
struct bcm2835_host *host = dev_id;
@@ -1288,7 +1288,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host)
/* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */
host->timeout_clk = mmc->f_max / 1000;
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
mmc->max_busy_timeout = (1 << 27) / host->timeout_clk;
#endif
/* host controller capabilities */
@@ -1345,7 +1345,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host)
init_waitqueue_head(&host->buf_ready_int);
bcm2835_mmc_init(host, 0);
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
ret = request_irq(host->irq, bcm2835_mmc_irq, 0 /*IRQF_SHARED*/,
mmc_hostname(mmc), host);
#else
@@ -1374,7 +1374,7 @@ untasklet:
static int bcm2835_mmc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_BCM2835
struct device_node *node = dev->of_node;
struct clk *clk;
#endif
@@ -1383,7 +1383,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev)
int ret;
struct mmc_host *mmc;
-#if !defined(CONFIG_OF) && !defined(FORCE_PIO)
+#if !defined(CONFIG_ARCH_BCM2835) && !defined(FORCE_PIO)
dma_cap_mask_t mask;
#endif
@@ -1408,7 +1408,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev)
host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT;
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
#ifndef FORCE_PIO
dma_cap_zero(mask);
/* we don't care about the channel, any would work */
@@ -1458,7 +1458,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev)
}
-#ifndef CONFIG_OF
+#ifndef CONFIG_ARCH_BCM2835
mmc->caps |= MMC_CAP_4_BIT_DATA;
#else
mmc_of_parse(mmc);
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index d134710..2e2b6d0 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1083,8 +1083,12 @@ static struct debugfs_blob_wrapper flat_dt_blob;
static int __init of_flat_dt_debugfs_export_fdt(void)
{
- struct dentry *d = debugfs_create_dir("device-tree", NULL);
+ struct dentry *d;
+ if (!initial_boot_params)
+ return -ENOENT;
+
+ d = debugfs_create_dir("device-tree", NULL);
if (!d)
return -ENOENT;
diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c
index 0b5322a..a3b65dc 100644
--- a/sound/soc/bcm/bcm2708-i2s.c
+++ b/sound/soc/bcm/bcm2708-i2s.c
@@ -493,15 +493,19 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream,
divf = dividend & BCM2708_CLK_DIVF_MASK;
}
- /* Set clock divider */
- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD
- | BCM2708_CLK_DIVI(divi)
- | BCM2708_CLK_DIVF(divf));
-
- /* Setup clock, but don't start it yet */
- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD
- | BCM2708_CLK_MASH(mash)
- | BCM2708_CLK_SRC(clk_src));
+ /* Clock should only be set up here if CPU is clock master */
+ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) ||
+ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) {
+ /* Set clock divider */
+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD
+ | BCM2708_CLK_DIVI(divi)
+ | BCM2708_CLK_DIVF(divf));
+
+ /* Setup clock, but don't start it yet */
+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD
+ | BCM2708_CLK_MASH(mash)
+ | BCM2708_CLK_SRC(clk_src));
+ }
/* Setup the frame format */
format = BCM2708_I2S_CHEN;
@@ -981,12 +985,19 @@ static int bcm2708_i2s_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id bcm2708_i2s_of_match[] = {
+ { .compatible = "brcm,bcm2708-i2s", },
+ {},
+};
+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,
},
};
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c
index 2685fe4..e2c61d1 100644
--- a/sound/soc/bcm/bcm2835-i2s.c
+++ b/sound/soc/bcm/bcm2835-i2s.c
@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = {
{ .compatible = "brcm,bcm2835-i2s", },
{},
};
+MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match);
static struct platform_driver bcm2835_i2s_driver = {
.probe = bcm2835_i2s_probe,
--
1.8.3.2

View file

@ -0,0 +1,630 @@
From 5f17e24bea60b696815d2c6cb578e1e23f61cd57 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 12 Nov 2014 17:07:02 +0000
Subject: [PATCH 064/114] Adding Device Tree support for some RPi audio cards
---
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 81 +++++++++++++++++++++++++
arch/arm/boot/dts/bcm2708-rpi-b.dts | 19 +++++-
arch/arm/boot/dts/bcm2708.dtsi | 18 ++++--
arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 +++++++++++
arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 ++++++++++++
arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 ++++++++++++
arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 ++++++++++++
arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 ++++++++++++
sound/soc/bcm/hifiberry_dac.c | 22 +++++++
sound/soc/bcm/hifiberry_dacplus.c | 22 +++++++
sound/soc/bcm/hifiberry_digi.c | 22 +++++++
sound/soc/bcm/iqaudio-dac.c | 16 +++++
sound/soc/codecs/pcm5102a.c | 7 +++
14 files changed, 393 insertions(+), 6 deletions(-)
create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
create mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts
create mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts
create mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts
create mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts
create mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index c727f71..adaebbb 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4ek.dtb
dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb
+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
@@ -520,6 +521,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6589-aquaris5.dtb
targets += dtbs dtbs_install
targets += $(dtb-y)
+
endif
# *.dtb used to be generated in the directory above. Clean out the
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
new file mode 100644
index 0000000..983c23f
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
@@ -0,0 +1,81 @@
+/dts-v1/;
+
+/include/ "bcm2708.dtsi"
+
+/ {
+ compatible = "brcm,bcm2708";
+ model = "Raspberry Pi Model B+";
+
+ aliases {
+ spi0 = &spi0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2s = &i2s;
+ gpio = &gpio;
+ sound = &sound;
+ };
+
+ sound: sound {
+ };
+};
+
+&gpio {
+ spi0_pins: spi0_pins {
+ brcm,pins = <7 8 9 10 11>;
+ brcm,function = <4>; /* alt0 */
+ };
+
+ i2c0_pins: i2c0 {
+ brcm,pins = <0 1>;
+ brcm,function = <4>;
+ };
+
+ i2c1_pins: i2c1 {
+ brcm,pins = <2 3>;
+ brcm,function = <4>;
+ };
+
+ i2s_pins: i2s {
+ brcm,pins = <18 19 20 21>;
+ brcm,function = <4>; /* alt0 */
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+
+ spidev@0{
+ compatible = "spidev";
+ reg = <0>; /* CE0 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <500000>;
+ };
+
+ spidev@1{
+ compatible = "spidev";
+ reg = <1>; /* CE1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <500000>;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+};
+
+&i2s {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s_pins>;
+};
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index 5893122..d8c6d15 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -4,12 +4,18 @@
/ {
compatible = "brcm,bcm2708";
- model = "Raspberry Pi";
+ model = "Raspberry Pi Model B";
aliases {
spi0 = &spi0;
i2c0 = &i2c0;
i2c1 = &i2c1;
+ i2s = &i2s;
+ gpio = &gpio;
+ sound = &sound;
+ };
+
+ sound: sound {
};
};
@@ -28,6 +34,11 @@
brcm,pins = <2 3>;
brcm,function = <4>;
};
+
+ i2s_pins: i2s {
+ brcm,pins = <28 29 30 31>;
+ brcm,function = <4>; /* alt0 */
+ };
};
&spi0 {
@@ -62,3 +73,9 @@
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <100000>;
};
+
+&i2s {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s_pins>;
+};
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index 2ca6d63..6b36128 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -7,11 +7,8 @@
interrupt-parent = <&intc>;
chosen {
- /*
- bootargs must be 1024 characters long because the
- VC bootloader can't expand it
- */
- bootargs = "console=ttyAMA0 ";
+ /* No padding required - the boot loader can do that. */
+ bootargs = "";
};
soc {
@@ -39,6 +36,17 @@
#interrupt-cells = <2>;
};
+ i2s: i2s@7e203000 {
+ compatible = "brcm,bcm2708-i2s";
+ reg = <0x7e203000 0x20>,
+ <0x7e101098 0x02>;
+
+ //dmas = <&dma 2>,
+ // <&dma 3>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
spi0: spi@7e204000 {
compatible = "brcm,bcm2708-spi";
reg = <0x7e204000 0x1000>;
diff --git a/arch/arm/boot/dts/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/hifiberry-dac-overlay.dts
new file mode 100644
index 0000000..5e7633a
--- /dev/null
+++ b/arch/arm/boot/dts/hifiberry-dac-overlay.dts
@@ -0,0 +1,34 @@
+// Definitions for HiFiBerry DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "hifiberry,hifiberry-dac";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target-path = "/";
+ __overlay__ {
+ pcm5102a-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5102a";
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts
new file mode 100644
index 0000000..deb9c62
--- /dev/null
+++ b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for HiFiBerry DAC+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "hifiberry,hifiberry-dacplus";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pcm5122@4d {
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4d>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/hifiberry-digi-overlay.dts
new file mode 100644
index 0000000..d0e0d8a
--- /dev/null
+++ b/arch/arm/boot/dts/hifiberry-digi-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for HiFiBerry Digi
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "hifiberry,hifiberry-digi";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ wm8804@3b {
+ #sound-dai-cells = <0>;
+ compatible = "wlf,wm8804";
+ reg = <0x3b>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/iqaudio-dac-overlay.dts
new file mode 100644
index 0000000..ea8173e
--- /dev/null
+++ b/arch/arm/boot/dts/iqaudio-dac-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for IQaudIO DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "iqaudio,iqaudio-dac";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pcm5122@4c {
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4c>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts
new file mode 100644
index 0000000..735d8ab
--- /dev/null
+++ b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for IQaudIO DAC+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "iqaudio,iqaudio-dac";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pcm5122@4c {
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4c>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c
index 4b70b45..3ab0f47 100644
--- a/sound/soc/bcm/hifiberry_dac.c
+++ b/sound/soc/bcm/hifiberry_dac.c
@@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev)
int ret = 0;
snd_rpi_hifiberry_dac.dev = &pdev->dev;
+
+ if (pdev->dev.of_node) {
+ struct device_node *i2s_node;
+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0];
+ i2s_node = of_parse_phandle(pdev->dev.of_node,
+ "i2s-controller", 0);
+
+ if (i2s_node) {
+ dai->cpu_dai_name = NULL;
+ dai->cpu_of_node = i2s_node;
+ dai->platform_name = NULL;
+ dai->platform_of_node = i2s_node;
+ }
+ }
+
ret = snd_soc_register_card(&snd_rpi_hifiberry_dac);
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
@@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev)
return snd_soc_unregister_card(&snd_rpi_hifiberry_dac);
}
+static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = {
+ { .compatible = "hifiberry,hifiberry-dac", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match);
+
static struct platform_driver snd_rpi_hifiberry_dac_driver = {
.driver = {
.name = "snd-hifiberry-dac",
.owner = THIS_MODULE,
+ .of_match_table = snd_rpi_hifiberry_dac_of_match,
},
.probe = snd_rpi_hifiberry_dac_probe,
.remove = snd_rpi_hifiberry_dac_remove,
diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c
index c63387b..11e4f39 100644
--- a/sound/soc/bcm/hifiberry_dacplus.c
+++ b/sound/soc/bcm/hifiberry_dacplus.c
@@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev)
int ret = 0;
snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
+
+ if (pdev->dev.of_node) {
+ struct device_node *i2s_node;
+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0];
+ i2s_node = of_parse_phandle(pdev->dev.of_node,
+ "i2s-controller", 0);
+
+ if (i2s_node) {
+ dai->cpu_dai_name = NULL;
+ dai->cpu_of_node = i2s_node;
+ dai->platform_name = NULL;
+ dai->platform_of_node = i2s_node;
+ }
+ }
+
ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
if (ret)
dev_err(&pdev->dev,
@@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev)
return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus);
}
+static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = {
+ { .compatible = "hifiberry,hifiberry-dacplus", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match);
+
static struct platform_driver snd_rpi_hifiberry_dacplus_driver = {
.driver = {
.name = "snd-rpi-hifiberry-dacplus",
.owner = THIS_MODULE,
+ .of_match_table = snd_rpi_hifiberry_dacplus_of_match,
},
.probe = snd_rpi_hifiberry_dacplus_probe,
.remove = snd_rpi_hifiberry_dacplus_remove,
diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c
index e4f769d..76af8a6 100644
--- a/sound/soc/bcm/hifiberry_digi.c
+++ b/sound/soc/bcm/hifiberry_digi.c
@@ -125,6 +125,21 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev)
int ret = 0;
snd_rpi_hifiberry_digi.dev = &pdev->dev;
+
+ if (pdev->dev.of_node) {
+ struct device_node *i2s_node;
+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0];
+ i2s_node = of_parse_phandle(pdev->dev.of_node,
+ "i2s-controller", 0);
+
+ if (i2s_node) {
+ dai->cpu_dai_name = NULL;
+ dai->cpu_of_node = i2s_node;
+ dai->platform_name = NULL;
+ dai->platform_of_node = i2s_node;
+ }
+ }
+
ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
@@ -137,10 +152,17 @@ static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev)
return snd_soc_unregister_card(&snd_rpi_hifiberry_digi);
}
+static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = {
+ { .compatible = "hifiberry,hifiberry-digi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match);
+
static struct platform_driver snd_rpi_hifiberry_digi_driver = {
.driver = {
.name = "snd-hifiberry-digi",
.owner = THIS_MODULE,
+ .of_match_table = snd_rpi_hifiberry_digi_of_match,
},
.probe = snd_rpi_hifiberry_digi_probe,
.remove = snd_rpi_hifiberry_digi_remove,
diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c
index 8d0e2ae..ee8cd6e 100644
--- a/sound/soc/bcm/iqaudio-dac.c
+++ b/sound/soc/bcm/iqaudio-dac.c
@@ -76,6 +76,21 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev)
int ret = 0;
snd_rpi_iqaudio_dac.dev = &pdev->dev;
+
+ if (pdev->dev.of_node) {
+ struct device_node *i2s_node;
+ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0];
+ i2s_node = of_parse_phandle(pdev->dev.of_node,
+ "i2s-controller", 0);
+
+ if (i2s_node) {
+ dai->cpu_dai_name = NULL;
+ dai->cpu_of_node = i2s_node;
+ dai->platform_name = NULL;
+ dai->platform_of_node = i2s_node;
+ }
+ }
+
ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
if (ret)
dev_err(&pdev->dev,
@@ -93,6 +108,7 @@ static const struct of_device_id iqaudio_of_match[] = {
{ .compatible = "iqaudio,iqaudio-dac", },
{},
};
+MODULE_DEVICE_TABLE(of, iqaudio_of_match);
static struct platform_driver snd_rpi_iqaudio_dac_driver = {
.driver = {
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
index 126f1e9..7c6598e 100644
--- a/sound/soc/codecs/pcm5102a.c
+++ b/sound/soc/codecs/pcm5102a.c
@@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id pcm5102a_of_match[] = {
+ { .compatible = "ti,pcm5102a", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
+
static struct platform_driver pcm5102a_codec_driver = {
.probe = pcm5102a_probe,
.remove = pcm5102a_remove,
.driver = {
.name = "pcm5102a-codec",
.owner = THIS_MODULE,
+ .of_match_table = pcm5102a_of_match,
},
};
--
1.8.3.2

View file

@ -0,0 +1,63 @@
From b99050b7f7480499855dec85be2deac75db5fc62 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 5 Dec 2014 17:26:26 +0000
Subject: [PATCH 65/99] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
---
drivers/of/fdt.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 2e2b6d0..badc6a3 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -901,22 +901,38 @@ int __init early_init_dt_scan_chosen(uns
/* Retrieve command line */
p = of_get_flat_dt_prop(node, "bootargs", &l);
- if (p != NULL && l > 0)
- strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
- p = of_get_flat_dt_prop(node, "bootargs-append", &l);
- if (p != NULL && l > 0)
- strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE));
/*
* CONFIG_CMDLINE is meant to be a default in case nothing else
* managed to set the command line, unless CONFIG_CMDLINE_FORCE
* is set in which case we override whatever was found earlier.
+ *
+ * However, it can be useful to be able to treat the default as
+ * a starting point to be extended using CONFIG_CMDLINE_EXTEND.
*/
+ ((char *)data)[0] = '\0';
+
#ifdef CONFIG_CMDLINE
-#ifndef CONFIG_CMDLINE_FORCE
- if (!((char *)data)[0])
+ strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+
+ if (p != NULL && l > 0) {
+#if defined(CONFIG_CMDLINE_EXTEND)
+ int len = strlen(data);
+ if (len > 0) {
+ strlcat(data, " ", COMMAND_LINE_SIZE);
+ len++;
+ }
+ strlcpy((char *)data + len, p, min((int)l, COMMAND_LINE_SIZE - len));
+#elif defined(CONFIG_CMDLINE_FORCE)
+ pr_warning("Ignoring bootargs property (using the default kernel command line)\n");
+#else
+ /* Neither extend nor force - just override */
+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
#endif
- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ }
+#else /* CONFIG_CMDLINE */
+ if (p != NULL && l > 0)
+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
#endif /* CONFIG_CMDLINE */
pr_debug("Command line is: %s\n", (char*)data);
--
1.8.3.2

View file

@ -0,0 +1,24 @@
From 42fd2d3e952c0a2c1455190eb208e5544b73da67 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 25 Nov 2014 13:39:03 +0000
Subject: [PATCH 066/114] config: Enable device tree
---
arch/arm/configs/bcmrpi_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 997e1f3..2cd8227 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -39,6 +39,7 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_MAC_PARTITION=y
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_ARCH_BCM2708=y
+CONFIG_BCM2708_DT=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CLEANCACHE=y
--
1.8.3.2

View file

@ -0,0 +1,49 @@
From 95560180ed73193d916519d0c949cd4816138be3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 16 Dec 2014 10:23:48 +0000
Subject: [PATCH 067/114] DT: Add overrides to enable i2c0, i2c1, spi and i2s
---
arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 10 ++++++++++
arch/arm/boot/dts/bcm2708-rpi-b.dts | 10 ++++++++++
2 files changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
index 983c23f..d9886c3 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
@@ -79,3 +79,13 @@
pinctrl-names = "default";
pinctrl-0 = <&i2s_pins>;
};
+
+
+/ {
+ __overrides__ {
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+ i2c1 = <&i2c1>,"status";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index d8c6d15..167b22b 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -79,3 +79,13 @@
pinctrl-names = "default";
pinctrl-0 = <&i2s_pins>;
};
+
+
+/ {
+ __overrides__ {
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+ i2c1 = <&i2c1>,"status";
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,299 @@
From f3c1830096661e270f11f2a33ffb7274f50c90a6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 18 Dec 2014 16:48:32 +0000
Subject: [PATCH 068/114] lirc-rpi: Add device tree support, and a suitable
overlay
The overlay supports DT parameters that match the old module
parameters, except that gpio_in_pull should be set using the
strings "up", "down" or "off".
lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode
---
arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 ++++++++++++
drivers/staging/media/lirc/lirc_rpi.c | 154 +++++++++++++++++++++++++++------
2 files changed, 183 insertions(+), 28 deletions(-)
create mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts
diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts
new file mode 100644
index 0000000..7d5d82b
--- /dev/null
+++ b/arch/arm/boot/dts/lirc-rpi-overlay.dts
@@ -0,0 +1,57 @@
+// Definitions for lirc-rpi module
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target-path = "/";
+ __overlay__ {
+ lirc_rpi: lirc_rpi {
+ compatible = "rpi,lirc-rpi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lirc_pins>;
+ status = "okay";
+
+ // Override autodetection of IR receiver circuit
+ // (0 = active high, 1 = active low, -1 = no override )
+ rpi,sense = <0xffffffff>;
+
+ // Software carrier
+ // (0 = off, 1 = on)
+ rpi,softcarrier = <1>;
+
+ // Invert output
+ // (0 = off, 1 = on)
+ rpi,invert = <0>;
+
+ // Enable debugging messages
+ // (0 = off, 1 = on)
+ rpi,debug = <0>;
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ lirc_pins: lirc_pins {
+ brcm,pins = <17 18>;
+ brcm,function = <1 0>; // out in
+ brcm,pull = <0 1>; // off down
+ };
+ };
+ };
+
+ __overrides__ {
+ gpio_out_pin = <&lirc_pins>,"brcm,pins:0";
+ gpio_in_pin = <&lirc_pins>,"brcm,pins:4";
+ gpio_in_pull = <&lirc_pins>,"brcm,pull:4";
+
+ sense = <&lirc_rpi>,"rpi,sense:0";
+ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0";
+ invert = <&lirc_rpi>,"rpi,invert:0";
+ debug = <&lirc_rpi>,"rpi,debug:0";
+ };
+};
diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c
index c688364..cd66ca2 100644
--- a/drivers/staging/media/lirc/lirc_rpi.c
+++ b/drivers/staging/media/lirc/lirc_rpi.c
@@ -40,6 +40,7 @@
#include <media/lirc_dev.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
+#include <linux/of_platform.h>
#include <linux/platform_data/bcm2708.h>
@@ -295,32 +296,117 @@ static int is_right_chip(struct gpio_chip *chip, void *data)
return 0;
}
+static inline int read_bool_property(const struct device_node *np,
+ const char *propname,
+ bool *out_value)
+{
+ u32 value = 0;
+ int err = of_property_read_u32(np, propname, &value);
+ if (err == 0)
+ *out_value = (value != 0);
+ return err;
+}
+
+static void read_pin_settings(struct device_node *node)
+{
+ u32 pin;
+ int index;
+
+ for (index = 0;
+ of_property_read_u32_index(
+ node,
+ "brcm,pins",
+ index,
+ &pin) == 0;
+ index++) {
+ u32 function;
+ int err;
+ err = of_property_read_u32_index(
+ node,
+ "brcm,function",
+ index,
+ &function);
+ if (err == 0) {
+ if (function == 1) /* Output */
+ gpio_out_pin = pin;
+ else if (function == 0) /* Input */
+ gpio_in_pin = pin;
+ }
+ }
+}
+
static int init_port(void)
{
int i, nlow, nhigh, ret;
+ struct device_node *node;
+
+ node = lirc_rpi_dev->dev.of_node;
gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
- if (!gpiochip)
+ /*
+ * Because of the lack of a setpull function, only support
+ * pinctrl-bcm2835 if using device tree.
+ */
+ if (!gpiochip && node)
+ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip);
+
+ if (!gpiochip) {
+ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n");
return -ENODEV;
+ }
+
+ if (node) {
+ struct device_node *pins_node;
+
+ pins_node = of_parse_phandle(node, "pinctrl-0", 0);
+ if (!pins_node) {
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": pinctrl settings not found!\n");
+ ret = -EINVAL;
+ goto exit_init_port;
+ }
+
+ read_pin_settings(pins_node);
+
+ of_property_read_u32(node, "rpi,sense", &sense);
+
+ read_bool_property(node, "rpi,softcarrier", &softcarrier);
+
+ read_bool_property(node, "rpi,invert", &invert);
+
+ read_bool_property(node, "rpi,debug", &debug);
- if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
- printk(KERN_ALERT LIRC_DRIVER_NAME
- ": cant claim gpio pin %d\n", gpio_out_pin);
- ret = -ENODEV;
- goto exit_init_port;
}
+ else
+ {
+ if (gpio_in_pin >= BCM2708_NR_GPIOS ||
+ gpio_out_pin >= BCM2708_NR_GPIOS) {
+ ret = -EINVAL;
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": invalid GPIO pin(s) specified!\n");
+ goto exit_init_port;
+ }
- if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
- printk(KERN_ALERT LIRC_DRIVER_NAME
- ": cant claim gpio pin %d\n", gpio_in_pin);
- ret = -ENODEV;
- goto exit_gpio_free_out_pin;
+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
+ printk(KERN_ALERT LIRC_DRIVER_NAME
+ ": cant claim gpio pin %d\n", gpio_out_pin);
+ ret = -ENODEV;
+ goto exit_init_port;
+ }
+
+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
+ printk(KERN_ALERT LIRC_DRIVER_NAME
+ ": cant claim gpio pin %d\n", gpio_in_pin);
+ ret = -ENODEV;
+ goto exit_gpio_free_out_pin;
+ }
+
+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull);
+ gpiochip->direction_input(gpiochip, gpio_in_pin);
+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
}
- bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull);
- gpiochip->direction_input(gpiochip, gpio_in_pin);
- gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
gpiochip->set(gpiochip, gpio_out_pin, invert);
irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
@@ -514,15 +600,23 @@ static struct lirc_driver driver = {
.owner = THIS_MODULE,
};
+static const struct of_device_id lirc_rpi_of_match[] = {
+ { .compatible = "rpi,lirc-rpi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, lirc_rpi_of_match);
+
static struct platform_driver lirc_rpi_driver = {
.driver = {
.name = LIRC_DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(lirc_rpi_of_match),
},
};
static int __init lirc_rpi_init(void)
{
+ struct device_node *node;
int result;
/* Init read buffer. */
@@ -537,15 +631,26 @@ static int __init lirc_rpi_init(void)
goto exit_buffer_free;
}
- lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
- if (!lirc_rpi_dev) {
- result = -ENOMEM;
- goto exit_driver_unregister;
+ node = of_find_compatible_node(NULL, NULL,
+ lirc_rpi_of_match[0].compatible);
+
+ if (node) {
+ /* DT-enabled */
+ lirc_rpi_dev = of_find_device_by_node(node);
+ WARN_ON(lirc_rpi_dev->dev.of_node != node);
+ of_node_put(node);
}
+ else {
+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
+ if (!lirc_rpi_dev) {
+ result = -ENOMEM;
+ goto exit_driver_unregister;
+ }
- result = platform_device_add(lirc_rpi_dev);
- if (result)
- goto exit_device_put;
+ result = platform_device_add(lirc_rpi_dev);
+ if (result)
+ goto exit_device_put;
+ }
return 0;
@@ -577,13 +682,6 @@ static int __init lirc_rpi_init_module(void)
if (result)
return result;
- if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) {
- result = -EINVAL;
- printk(KERN_ERR LIRC_DRIVER_NAME
- ": invalid GPIO pin(s) specified!\n");
- goto exit_rpi;
- }
-
result = init_port();
if (result < 0)
goto exit_rpi;
--
1.8.3.2

View file

@ -0,0 +1,137 @@
From 31b85ba13aa394c98f2d6955b55f3f9a0623c14d Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 6 Jan 2015 12:06:55 +0000
Subject: [PATCH 069/114] Fix the activity LED in DT mode
Add a "leds" node to the base DTBs, and a subnode for the activity
LED. You can change the LED function like this:
dtparam=act_led_trigger=heartbeat
Add aliases for the other main nodes (soc, intc).
Issue: linux #757
---
arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 18 ++++++++++++++----
arch/arm/boot/dts/bcm2708-rpi-b.dts | 18 ++++++++++++++----
arch/arm/boot/dts/bcm2708.dtsi | 11 ++++++++++-
3 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
index d9886c3..95f03ba 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
@@ -7,11 +7,14 @@
model = "Raspberry Pi Model B+";
aliases {
+ soc = &soc;
spi0 = &spi0;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2s = &i2s;
gpio = &gpio;
+ intc = &intc;
+ leds = &leds;
sound = &sound;
};
@@ -80,12 +83,19 @@
pinctrl-0 = <&i2s_pins>;
};
+&act_led {
+ gpios = <&gpio 47 0>;
+};
/ {
__overrides__ {
- i2s = <&i2s>,"status";
- spi = <&spi0>,"status";
- i2c0 = <&i2c0>,"status";
- i2c1 = <&i2c1>,"status";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+ i2c1 = <&i2c1>,"status";
+
+ act_led_gpio = <&act_led>,"gpios:4";
+ act_led_activelow = <&act_led>,"gpios:8";
+ act_led_trigger = <&act_led>,"linux,default-trigger";
};
};
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index 167b22b..0631f45 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -7,11 +7,14 @@
model = "Raspberry Pi Model B";
aliases {
+ soc = &soc;
spi0 = &spi0;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2s = &i2s;
gpio = &gpio;
+ intc = &intc;
+ leds = &leds;
sound = &sound;
};
@@ -80,12 +83,19 @@
pinctrl-0 = <&i2s_pins>;
};
+&act_led {
+ gpios = <&gpio 16 1>;
+};
/ {
__overrides__ {
- i2s = <&i2s>,"status";
- spi = <&spi0>,"status";
- i2c0 = <&i2c0>,"status";
- i2c1 = <&i2c1>,"status";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+ i2c1 = <&i2c1>,"status";
+
+ act_led_gpio = <&act_led>,"gpios:4";
+ act_led_activelow = <&act_led>,"gpios:8";
+ act_led_trigger = <&act_led>,"linux,default-trigger";
};
};
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index 6b36128..1b56cb5 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -11,7 +11,7 @@
bootargs = "";
};
- soc {
+ soc: soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
@@ -76,6 +76,15 @@
#size-cells = <0>;
status = "disabled";
};
+
+ leds: leds {
+ compatible = "gpio-leds";
+
+ act_led: act {
+ label = "ACT";
+ linux,default-trigger = "mmc0";
+ };
+ };
};
clocks {
--
1.8.3.2

View file

@ -0,0 +1,115 @@
From 2fea9b14e39bd6c64e362ba7d170b67d09206987 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 15 Jan 2015 10:39:06 +0000
Subject: [PATCH 070/114] Adding w1-gpio device tree overlays
N.B. Requires firmware supporting multi-target overrides
w1-gpio-overlay:
Use if a pullup pin is not required.
Parameters:
gpiopin=<i/o pin> // default 4
w1-gpio-pullup-overlay:
Use if a pullup pin is required.
Parameters:
gpiopin=<i/o pin> // default 4
pullup=<pullup pin> // default 5
---
arch/arm/boot/dts/w1-gpio-overlay.dts | 37 ++++++++++++++++++++++++++
arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 39 ++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
create mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts
create mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts
diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts
new file mode 100644
index 0000000..b2c5ee2
--- /dev/null
+++ b/arch/arm/boot/dts/w1-gpio-overlay.dts
@@ -0,0 +1,37 @@
+// Definitions for lirc-rpi module
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target-path = "/";
+ __overlay__ {
+
+ w1: onewire@0 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_pins>;
+ gpios = <&gpio 4 0>;
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ w1_pins: w1_pins {
+ brcm,pins = <4>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+ };
+ };
+
+ __overrides__ {
+ gpiopin = <&w1>,"gpios:4",
+ <&w1_pins>,"brcm,pins:0";
+ };
+};
diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts
new file mode 100644
index 0000000..b3e97c2
--- /dev/null
+++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for lirc-rpi module
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target-path = "/";
+ __overlay__ {
+
+ w1: onewire@0 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_pins>;
+ gpios = <&gpio 4 0>, <&gpio 5 1>;
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ w1_pins: w1_pins {
+ brcm,pins = <4 5>;
+ brcm,function = <0 1>; // in out
+ brcm,pull = <0 0>; // off off
+ };
+ };
+ };
+
+ __overrides__ {
+ gpiopin = <&w1>,"gpios:4",
+ <&w1_pins>,"brcm,pins:0";
+ pullup = <&w1>,"gpios:16",
+ <&w1_pins>,"brcm,pins:4";
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,26 @@
From 960ce56201a7521051a2dbf84ab5e3acb95d5ce3 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 21 Jan 2015 22:46:02 +0000
Subject: [PATCH 071/114] config: Enable CONFIG_PPS
---
arch/arm/configs/bcmrpi_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 2cd8227..36aca2b 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -544,6 +544,9 @@ CONFIG_I2C_BCM2708=m
CONFIG_SPI=y
CONFIG_SPI_BCM2708=m
CONFIG_SPI_SPIDEV=y
+CONFIG_PPS=m
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_ARIZONA=m
CONFIG_W1=m
--
1.8.3.2

View file

@ -0,0 +1,52 @@
From 946fa2807124fa8ef981f4b6c47abe1d587b5cad Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 21 Jan 2015 23:47:33 +0000
Subject: [PATCH 072/114] config: Add CONFIG_IP_NF options
---
arch/arm/configs/bcmrpi_defconfig | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 36aca2b..665b01e 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -208,13 +208,16 @@ CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m
CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_NAT_IPV4=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
@@ -223,7 +226,6 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_NF_NAT_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -238,6 +240,9 @@ CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
--
1.8.3.2

View file

@ -0,0 +1,90 @@
From 6a0570d2c5ae88c6170484ec7b521994bbb450b1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 23 Jan 2015 12:04:59 +0000
Subject: [PATCH 073/114] config: Restore some missing options
---
arch/arm/configs/bcmrpi_defconfig | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 665b01e..41b90b4 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -484,6 +484,8 @@ CONFIG_AR5523=m
CONFIG_B43=m
# CONFIG_B43_PHY_N is not set
CONFIG_B43LEGACY=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_USB=y
CONFIG_HOSTAP=m
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
@@ -524,6 +526,7 @@ CONFIG_INPUT_POWERMATE=m
CONFIG_INPUT_YEALINK=m
CONFIG_INPUT_CM109=m
CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
CONFIG_INPUT_ADXL34X=m
CONFIG_INPUT_CMA3000=m
CONFIG_SERIO=m
@@ -545,6 +548,7 @@ CONFIG_BCM_VC_CMA=y
CONFIG_BCM_VC_SM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX=m
CONFIG_I2C_BCM2708=m
CONFIG_SPI=y
CONFIG_SPI_BCM2708=m
@@ -724,6 +728,7 @@ CONFIG_RADIO_SI470X=y
CONFIG_USB_SI470X=m
CONFIG_I2C_SI470X=m
CONFIG_RADIO_SI4713=m
+CONFIG_I2C_SI4713=m
CONFIG_USB_MR800=m
CONFIG_USB_DSBR=m
CONFIG_RADIO_SHARK=m
@@ -735,6 +740,15 @@ CONFIG_RADIO_SAA7706H=m
CONFIG_RADIO_TEF6862=m
CONFIG_RADIO_WL1273=m
CONFIG_RADIO_WL128X=m
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_UDA1342=m
+CONFIG_VIDEO_SONY_BTF_MPX=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_TW2804=m
+CONFIG_VIDEO_TW9903=m
+CONFIG_VIDEO_TW9906=m
+CONFIG_VIDEO_OV7640=m
+CONFIG_VIDEO_MT9V011=m
CONFIG_FB=y
CONFIG_FB_BCM2708=y
# CONFIG_BACKLIGHT_GENERIC is not set
@@ -783,6 +797,7 @@ CONFIG_HID_CYPRESS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELECOM=m
+CONFIG_HID_ELO=m
CONFIG_HID_EZKEY=m
CONFIG_HID_HOLTEK=m
CONFIG_HID_KEYTOUCH=m
@@ -1042,6 +1057,7 @@ CONFIG_F2FS_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFS_FSCACHE=y
CONFIG_NFSD=m
@@ -1116,8 +1132,6 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA1_ARM=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
--
1.8.3.2

View file

@ -0,0 +1,72 @@
From 2a72cdffabd2dd290d126c9a4e544bb65b537993 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <daniel@hifiberry.com>
Date: Fri, 23 Jan 2015 16:41:17 +0100
Subject: [PATCH 074/114] TAS5713: return error if initialisation fails
Existing TAS5713 driver logs errors during initialisation, but does not return
an error code. Therefore even if initialisation fails, the driver will still be
loaded, but won't work. This patch fixes this. I2C communication error will now
reported correctly by a non-zero return code.
---
sound/soc/codecs/tas5713.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c
index a24c1da..9b27138 100644
--- a/sound/soc/codecs/tas5713.c
+++ b/sound/soc/codecs/tas5713.c
@@ -182,33 +182,40 @@ static int tas5713_probe(struct snd_soc_codec *codec)
// Reset error
ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
+ if (ret < 0) return ret;
// Trim oscillator
- ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00);
+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00);
+ if (ret < 0) return ret;
msleep(1000);
// Reset error
ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
+ if (ret < 0) return ret;
// Clock mode: 44/48kHz, MCLK=64xfs
ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60);
+ if (ret < 0) return ret;
// I2S 24bit
ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05);
+ if (ret < 0) return ret;
// Unmute
ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
+ if (ret < 0) return ret;
ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00);
+ if (ret < 0) return ret;
// Set volume to 0db
ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00);
+ if (ret < 0) return ret;
// Now start programming the default initialization sequence
for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) {
ret = i2c_master_send(i2c,
tas5713_init_sequence[i].data,
tas5713_init_sequence[i].size);
-
if (ret < 0) {
printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret);
}
@@ -216,7 +223,7 @@ static int tas5713_probe(struct snd_soc_codec *codec)
// Unmute
ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
-
+ if (ret < 0) return ret;
return 0;
}
--
1.8.3.2

View file

@ -0,0 +1,43 @@
From 672e48427ca17fadd59d294eec56476dd6a75398 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 23 Jan 2015 15:18:03 +0000
Subject: [PATCH 076/114] BCM2708_DT: Build the overlays as well
---
arch/arm/boot/dts/Makefile | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index adaebbb..3c7f539 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -55,6 +55,14 @@ dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb
dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb
+dtb-$(CONFIG_BCM2708_DT) += hifiberry-dac-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += hifiberry-dacplus-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += hifiberry-digi-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += iqaudio-dac-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += w1-gpio-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += w1-gpio-pullup-overlay.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
@@ -524,6 +532,11 @@ targets += $(dtb-y)
endif
+# Enable fixups to support overlays on BCM2708 platforms
+ifeq ($(CONFIG_BCM2708_DT),y)
+ DTC_FLAGS ?= -@
+endif
+
# *.dtb used to be generated in the directory above. Clean out the
# old build results so people don't accidentally use them.
dtbs: $(addprefix $(obj)/, $(dtb-y))
--
1.8.3.2

View file

@ -0,0 +1,72 @@
From 555c5c21ed88de7efa91ce45668ac11416eb29dd Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Sun, 25 Jan 2015 19:41:06 +0100
Subject: [PATCH 077/114] Add device tree overlay for HiFiBerry Amp/Amp+
This patch add the missing device tree file for the HiFiBerry Amp and Amp+ boards.
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/hifiberry-amp-overlay.dts | 39 +++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
create mode 100644 arch/arm/boot/dts/hifiberry-amp-overlay.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 3c7f539..4e1ec2d 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -58,6 +58,7 @@ dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb
dtb-$(CONFIG_BCM2708_DT) += hifiberry-dac-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += hifiberry-dacplus-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += hifiberry-digi-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += hifiberry-amp-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dac-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb
diff --git a/arch/arm/boot/dts/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/hifiberry-amp-overlay.dts
new file mode 100644
index 0000000..2c81448
--- /dev/null
+++ b/arch/arm/boot/dts/hifiberry-amp-overlay.dts
@@ -0,0 +1,39 @@
+// Definitions for HiFiBerry Amp/Amp+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "hifiberry,hifiberry-amp";
+ i2s-controller = <&i2s>;
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ tas5713@1b {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tas5713";
+ reg = <0x1b>;
+ status = "okay";
+ };
+ };
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,68 @@
From 4cd9d10a9cd482e993dcfe3bd1d576ad0d11c3c3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 26 Jan 2015 09:18:24 +0000
Subject: [PATCH 078/114] Add pps-gpio DT overlay
Parameters:
gpiopin=<input pin> // Default 18
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/pps-gpio-overlay.dts | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 arch/arm/boot/dts/pps-gpio-overlay.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 4e1ec2d..4d1224b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -62,6 +62,7 @@ dtb-$(CONFIG_BCM2708_DT) += hifiberry-amp-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dac-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += pps-gpio-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-pullup-overlay.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
diff --git a/arch/arm/boot/dts/pps-gpio-overlay.dts b/arch/arm/boot/dts/pps-gpio-overlay.dts
new file mode 100644
index 0000000..40bf0e1
--- /dev/null
+++ b/arch/arm/boot/dts/pps-gpio-overlay.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+ fragment@0 {
+ target-path = "/";
+ __overlay__ {
+ pps: pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pps_pins>;
+ gpios = <&gpio 18 0>;
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ pps_pins: pps_pins {
+ brcm,pins = <18>;
+ brcm,function = <0>; // in
+ brcm,pull = <0>; // off
+ };
+ };
+ };
+
+ __overrides__ {
+ gpiopin = <&pps>,"gpios:4",
+ <&pps_pins>,"brcm,pins:0";
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,24 @@
From 2661fe9121d21ae3ba756b98b545a509b63a71d7 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 26 Jan 2015 14:32:18 +0000
Subject: [PATCH 079/114] config: Remove STRICT_DEVMEM
---
arch/arm/configs/bcmrpi_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index 41b90b4..fd7c022 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -1124,7 +1124,6 @@ CONFIG_FUNCTION_PROFILER=y
CONFIG_KGDB=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
-CONFIG_STRICT_DEVMEM=y
CONFIG_CRYPTO_USER=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
--
1.8.3.2

View file

@ -0,0 +1,49 @@
From 6a63fb6bd7120af9a760fa0f2db9461bfcf29791 Mon Sep 17 00:00:00 2001
From: Serge Schneider <serge@raspberrypi.org>
Date: Wed, 3 Sep 2014 14:44:22 +0100
Subject: [PATCH 080/114] I2C: Only register the I2C device for the current
board revision
---
arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 2c6a29d..b36037b 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -93,6 +93,7 @@ static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
static unsigned w1_gpio_pin = W1_GPIO;
static unsigned w1_gpio_pullup = W1_PULLUP;
+static bool vc_i2c_override = false;
static unsigned use_dt = 0;
@@ -862,8 +863,15 @@ void __init bcm2708_init(void)
bcm_register_device(&bcm2835_thermal_device);
bcm_register_device_dt(&bcm2708_spi_device);
- bcm_register_device_dt(&bcm2708_bsc0_device);
- bcm_register_device_dt(&bcm2708_bsc1_device);
+
+ if (vc_i2c_override) {
+ bcm_register_device_dt(&bcm2708_bsc0_device);
+ bcm_register_device_dt(&bcm2708_bsc1_device);
+ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) {
+ bcm_register_device_dt(&bcm2708_bsc0_device);
+ } else {
+ bcm_register_device_dt(&bcm2708_bsc1_device);
+ }
#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE)
bcm_register_device_dt(&bcm2708_i2s_device);
@@ -1093,3 +1101,5 @@ module_param(disk_led_active_low, uint, 0644);
module_param(reboot_part, uint, 0644);
module_param(w1_gpio_pin, uint, 0644);
module_param(w1_gpio_pullup, uint, 0644);
+module_param(vc_i2c_override, bool, 0644);
+MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
--
1.8.3.2

View file

@ -0,0 +1,79 @@
From 47a2d8098a9523435aec2fff1389ae92fd8791a9 Mon Sep 17 00:00:00 2001
From: Timo Kokkonen <tjko@iki.fi>
Date: Wed, 29 Oct 2014 23:30:30 -0700
Subject: [PATCH 081/114] Added support to reserve/enable a GPIO pin to be used
from pps-gpio module (LinuxPPS). Enable PPS modules in default config for
RPi.
---
arch/arm/mach-bcm2708/bcm2708.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index b36037b..762e17c 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -37,6 +37,7 @@
#include <linux/spi/spi.h>
#include <linux/gpio/machine.h>
#include <linux/w1-gpio.h>
+#include <linux/pps-gpio.h>
#include <linux/version.h>
#include <linux/clkdev.h>
@@ -93,6 +94,7 @@ static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
static unsigned w1_gpio_pin = W1_GPIO;
static unsigned w1_gpio_pullup = W1_PULLUP;
+static int pps_gpio_pin = -1;
static bool vc_i2c_override = false;
static unsigned use_dt = 0;
@@ -274,6 +276,19 @@ static struct platform_device w1_device = {
};
#endif
+static struct pps_gpio_platform_data pps_gpio_info = {
+ .assert_falling_edge = false,
+ .capture_clear = false,
+ .gpio_pin = -1,
+ .gpio_label = "PPS",
+};
+
+static struct platform_device pps_gpio_device = {
+ .name = "pps-gpio",
+ .id = PLATFORM_DEVID_NONE,
+ .dev.platform_data = &pps_gpio_info,
+};
+
static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
static struct platform_device bcm2708_fb_device = {
@@ -841,6 +856,16 @@ void __init bcm2708_init(void)
#ifdef CONFIG_BCM2708_GPIO
bcm_register_device_dt(&bcm2708_gpio_device);
#endif
+
+#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE)
+ if (!use_dt && (pps_gpio_pin >= 0)) {
+ pr_info("bcm2708: GPIO %d setup as pps-gpio device\n", pps_gpio_pin);
+ pps_gpio_info.gpio_pin = pps_gpio_pin;
+ pps_gpio_device.id = pps_gpio_pin;
+ bcm_register_device(&pps_gpio_device);
+ }
+#endif
+
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
w1_gpio_pdata.pin = w1_gpio_pin;
w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
@@ -1101,5 +1126,7 @@ module_param(disk_led_active_low, uint, 0644);
module_param(reboot_part, uint, 0644);
module_param(w1_gpio_pin, uint, 0644);
module_param(w1_gpio_pullup, uint, 0644);
+module_param(pps_gpio_pin, int, 0644);
+MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS");
module_param(vc_i2c_override, bool, 0644);
MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
--
1.8.3.2

View file

@ -0,0 +1,25 @@
From a2a3c09223aa520e08cc34c496dc286843eecf92 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 26 Jan 2015 15:26:10 +0000
Subject: [PATCH 082/114] BCM2708_DT: Correct length of the peripheral space
---
arch/arm/boot/dts/bcm2708.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
index 1b56cb5..d879316 100644
--- a/arch/arm/boot/dts/bcm2708.dtsi
+++ b/arch/arm/boot/dts/bcm2708.dtsi
@@ -15,7 +15,7 @@
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0x7e000000 0x20000000 0x02000000>;
+ ranges = <0x7e000000 0x20000000 0x01000000>;
intc: interrupt-controller {
compatible = "brcm,bcm2708-armctrl-ic";
--
1.8.3.2

View file

@ -0,0 +1,54 @@
From 82fe3c57ba4c661c119a08567b9aaa5b63de07e1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 28 Jan 2015 16:22:04 +0000
Subject: [PATCH 083/114] BCM2708_DT: Add pcf8523-rtc overlay
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/pcf8523-rtc-overlay.dts | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+)
create mode 100644 arch/arm/boot/dts/pcf8523-rtc-overlay.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 4d1224b..86c6190 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -62,6 +62,7 @@ dtb-$(CONFIG_BCM2708_DT) += hifiberry-amp-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dac-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += pcf8523-rtc-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += pps-gpio-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-pullup-overlay.dtb
diff --git a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts
new file mode 100644
index 0000000..0071f62
--- /dev/null
+++ b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts
@@ -0,0 +1,22 @@
+// Definitions for PCF8523 Real Time Clock
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pcf8523@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ status = "okay";
+ };
+ };
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,77 @@
From a09a8ebce7251e2a42668bd5ae57c12ed24fdca8 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <daniel@hifiberry.com>
Date: Sat, 31 Jan 2015 16:07:56 +0100
Subject: [PATCH 084/114] Add a parameter to turn off SPDIF output if no audio
is playing
This patch adds the paramater auto_shutdown_output to the kernel module.
Default behaviour of the module is the same, but when auto_shutdown_output
is set to 1, the SPDIF oputput will shutdown if no stream is playing.
---
sound/soc/bcm/hifiberry_digi.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c
index 76af8a6..b0e3d28 100644
--- a/sound/soc/bcm/hifiberry_digi.c
+++ b/sound/soc/bcm/hifiberry_digi.c
@@ -26,6 +26,11 @@
#include "../codecs/wm8804.h"
+static short int auto_shutdown_output = 0;
+module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped");
+
+
static int samplerate=44100;
static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
@@ -38,6 +43,25 @@ static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int snd_rpi_hifiberry_digi_startup(struct snd_pcm_substream *substream) {
+ /* turn on digital output */
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00);
+ return 0;
+}
+
+static void snd_rpi_hifiberry_digi_shutdown(struct snd_pcm_substream *substream) {
+ /* turn off output */
+ if (auto_shutdown_output) {
+ /* turn off output */
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c);
+ }
+}
+
+
static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -70,7 +94,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
break;
default:
dev_err(substream->pcm->dev,
- "Failed to set WM8804 SYSCLK, unsupported samplerate\n");
+ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n",
+ samplerate);
}
snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div);
@@ -96,6 +121,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
/* machine stream operations */
static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = {
.hw_params = snd_rpi_hifiberry_digi_hw_params,
+ .startup = snd_rpi_hifiberry_digi_startup,
+ .shutdown = snd_rpi_hifiberry_digi_shutdown,
};
static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = {
--
1.8.3.2

View file

@ -0,0 +1,24 @@
From c12aab11b88318b9dde0960f5309cf4c0b2af579 Mon Sep 17 00:00:00 2001
From: Joerg Hohensohn <joerg.hohensohn@dreamchip.de>
Date: Sun, 1 Feb 2015 22:08:03 +0100
Subject: [PATCH 085/114] bugfix for 32kHz sample rate, was missing
---
sound/soc/bcm/hifiberry_digi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c
index b0e3d28..133d51b 100644
--- a/sound/soc/bcm/hifiberry_digi.c
+++ b/sound/soc/bcm/hifiberry_digi.c
@@ -80,6 +80,7 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
samplerate = params_rate(params);
switch (samplerate) {
+ case 32000:
case 44100:
case 48000:
case 88200:
--
1.8.3.2

View file

@ -0,0 +1,32 @@
From ee23837a8a79b6ab67cab13d63804ba5a7260528 Mon Sep 17 00:00:00 2001
From: Ryan Coe <bluemrp9@gmail.com>
Date: Sat, 31 Jan 2015 18:25:49 -0700
Subject: [PATCH 086/114] Update ds1307 driver for device-tree support
Signed-off-by: Ryan Coe <bluemrp9@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bb43cf7..dadd4fb 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1241,6 +1241,14 @@ static int ds1307_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id ds1307_of_match[] = {
+ { .compatible = "maxim,ds1307" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ds1307_of_match);
+#endif
+
static struct i2c_driver ds1307_driver = {
.driver = {
.name = "rtc-ds1307",
--
1.8.3.2

View file

@ -0,0 +1,55 @@
From fe72f81ecb7578418207444186fa035262530946 Mon Sep 17 00:00:00 2001
From: Ryan Coe <bluemrp9@gmail.com>
Date: Sat, 31 Jan 2015 18:26:03 -0700
Subject: [PATCH 087/114] Add device-tree overlay for ds1307
Signed-off-by: Ryan Coe <bluemrp9@gmail.com>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/ds1307-rtc-overlay.dts | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+)
create mode 100644 arch/arm/boot/dts/ds1307-rtc-overlay.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 86c6190..1b66478 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -64,6 +64,7 @@ dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += pcf8523-rtc-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += pps-gpio-overlay.dtb
+dtb-$(CONFIG_BCM2708_DT) += ds1307-rtc-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-overlay.dtb
dtb-$(CONFIG_BCM2708_DT) += w1-gpio-pullup-overlay.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
diff --git a/arch/arm/boot/dts/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/ds1307-rtc-overlay.dts
new file mode 100644
index 0000000..7d27044
--- /dev/null
+++ b/arch/arm/boot/dts/ds1307-rtc-overlay.dts
@@ -0,0 +1,22 @@
+// Definitions for DS1307 Real Time Clock
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ds1307@68 {
+ compatible = "maxim,ds1307";
+ reg = <0x68>;
+ status = "okay";
+ };
+ };
+ };
+};
--
1.8.3.2

View file

@ -0,0 +1,24 @@
From e985ecbccdd44f3941ce7652103520d68edeeb77 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sun, 1 Feb 2015 12:10:25 +0000
Subject: [PATCH 088/114] config: Add DVB_USB_DVBSKY
---
arch/arm/configs/bcmrpi_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index fd7c022..0453a38 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -715,6 +715,7 @@ CONFIG_DVB_USB_GL861=m
CONFIG_DVB_USB_LME2510=m
CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
+CONFIG_DVB_USB_DVBSKY=m
CONFIG_SMS_USB_DRV=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
CONFIG_DVB_AS102=m
--
1.8.3.2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,222 @@
From 1ef33cbb3347c38f563de1c7df7d103f8b7d23ca Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 20 Jun 2014 17:19:27 +0100
Subject: [PATCH 090/114] bcm2709: Simplify and strip down IRQ handler
---
arch/arm/include/asm/entry-macro-multi.S | 2 +
arch/arm/mach-bcm2709/include/mach/entry-macro.S | 169 +++++++++++------------
2 files changed, 85 insertions(+), 86 deletions(-)
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
index 469a2b3..9c0a7eb 100644
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -1,5 +1,6 @@
#include <asm/assembler.h>
+#ifndef CONFIG_ARCH_BCM2709
/*
* Interrupt handling. Preserves r7, r8, r9
*/
@@ -28,6 +29,7 @@
#endif
9997:
.endm
+#endif
.macro arch_irq_handler, symbol_name
.align 5
diff --git a/arch/arm/mach-bcm2709/include/mach/entry-macro.S b/arch/arm/mach-bcm2709/include/mach/entry-macro.S
index d08591b..101d9f1 100644
--- a/arch/arm/mach-bcm2709/include/mach/entry-macro.S
+++ b/arch/arm/mach-bcm2709/include/mach/entry-macro.S
@@ -22,102 +22,99 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
- .macro disable_fiq
- .endm
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE)
- .endm
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
+ /* get core number */
+ mrc p15, 0, \base, c0, c0, 5
+ ubfx \base, \base, #0, #2
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- /* get core number */
- mrc p15, 0, \tmp, c0, c0, 5
- ubfx \tmp, \tmp, #0, #2
+ /* get core's local interrupt controller */
+ ldr \irqstat, = __io_address(ARM_LOCAL_IRQ_PENDING0) @ local interrupt source
+ add \irqstat, \irqstat, \base, lsl #2
+ ldr \tmp, [\irqstat]
- /* get core's local interrupt controller */
- ldr \irqstat, = __io_address(ARM_LOCAL_IRQ_PENDING0) @ local interrupt source
- add \irqstat, \irqstat, \tmp, lsl #2
- ldr \tmp, [\irqstat]
- /* ignore gpu interrupt */
- bic \tmp, #0x100
- /* ignore mailbox interrupts */
- bics \tmp, #0xf0
- beq 1005f
+ /* test for mailbox0 (IPI) interrupt */
+ tst \tmp, #0x10
+ beq 1030f
- @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
- @ N.B. CLZ is an ARM5 instruction.
- mov \irqnr, #(ARM_IRQ_LOCAL_BASE + 31)
- sub \irqstat, \tmp, #1
- eor \irqstat, \irqstat, \tmp
- clz \tmp, \irqstat
- sub \irqnr, \tmp
- b 1020f
-1005:
- /* get core number */
- mrc p15, 0, \tmp, c0, c0, 5
- ubfx \tmp, \tmp, #0, #2
+ /* get core's mailbox interrupt control */
+ ldr \irqstat, = __io_address(ARM_LOCAL_MAILBOX0_CLR0) @ mbox_clr
+ add \irqstat, \irqstat, \base, lsl #4
+ ldr \tmp, [\irqstat]
+ clz \tmp, \tmp
+ rsb \irqnr, \tmp, #31
+ mov \tmp, #1
+ lsl \tmp, \irqnr
+ str \tmp, [\irqstat] @ clear interrupt source
+ dsb
+ mov r1, sp
+ adr lr, BSYM(1b)
+ b do_IPI
- cmp \tmp, #1
- beq 1020f
- cmp \tmp, #2
- beq 1020f
- cmp \tmp, #3
- beq 1020f
+1030:
+ /* check gpu interrupt */
+ tst \tmp, #0x100
+ beq 1040f
- /* get masked status */
- ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
- mov \irqnr, #(ARM_IRQ0_BASE + 31)
- and \tmp, \irqstat, #0x300 @ save bits 8 and 9
- /* clear bits 8 and 9, and test */
- bics \irqstat, \irqstat, #0x300
- bne 1010f
+ ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE)
+ /* get masked status */
+ ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
+ mov \irqnr, #(ARM_IRQ0_BASE + 31)
+ and \tmp, \irqstat, #0x300 @ save bits 8 and 9
+ /* clear bits 8 and 9, and test */
+ bics \irqstat, \irqstat, #0x300
+ bne 1010f
- tst \tmp, #0x100
- ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
- movne \irqnr, #(ARM_IRQ1_BASE + 31)
- @ Mask out the interrupts also present in PEND0 - see SW-5809
- bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
- bicne \irqstat, #((1<<18) | (1<<19))
- bne 1010f
-
- tst \tmp, #0x200
- ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
- movne \irqnr, #(ARM_IRQ2_BASE + 31)
- @ Mask out the interrupts also present in PEND0 - see SW-5809
- bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
- bicne \irqstat, #((1<<30))
- beq 1020f
+ tst \tmp, #0x100
+ ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
+ movne \irqnr, #(ARM_IRQ1_BASE + 31)
+ @ Mask out the interrupts also present in PEND0 - see SW-5809
+ bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
+ bicne \irqstat, #((1<<18) | (1<<19))
+ bne 1010f
+ tst \tmp, #0x200
+ ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
+ movne \irqnr, #(ARM_IRQ2_BASE + 31)
+ @ Mask out the interrupts also present in PEND0 - see SW-5809
+ bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
+ bicne \irqstat, #((1<<30))
+ beq 1020f
1010:
- @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
- @ N.B. CLZ is an ARM5 instruction.
- sub \tmp, \irqstat, #1
- eor \irqstat, \irqstat, \tmp
- clz \tmp, \irqstat
- sub \irqnr, \tmp
+ @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
+ sub \tmp, \irqstat, #1
+ eor \irqstat, \irqstat, \tmp
+ clz \tmp, \irqstat
+ sub \irqnr, \tmp
+ b 1050f
+1040:
+ cmp \tmp, #0
+ beq 1020f
-1020: @ EQ will be set if no irqs pending
+ /* handle local (e.g. timer) interrupts */
+ @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
+ mov \irqnr, #(ARM_IRQ_LOCAL_BASE + 31)
+ sub \irqstat, \tmp, #1
+ eor \irqstat, \irqstat, \tmp
+ clz \tmp, \irqstat
+ sub \irqnr, \tmp
+1050:
+ mov r1, sp
+ @
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ @
+ adr lr, BSYM(1b)
+ b asm_do_IRQ
- .endm
+1020: @ EQ will be set if no irqs pending
+ .endm
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- /* get core number */
- mrc p15, 0, \tmp, c0, c0, 5
- ubfx \tmp, \tmp, #0, #2
- /* get core's mailbox interrupt control */
- ldr \irqstat, = __io_address(ARM_LOCAL_MAILBOX0_CLR0) @ mbox_clr
- add \irqstat, \irqstat, \tmp, lsl #4
- ldr \tmp, [\irqstat]
- cmp \tmp, #0
- beq 1030f
- clz \tmp, \tmp
- rsb \irqnr, \tmp, #31
- mov \tmp, #1
- lsl \tmp, \irqnr
- str \tmp, [\irqstat] @ clear interrupt source
- dsb
-1030: @ EQ will be set if no irqs pending
- .endm
+/*
+ * Interrupt handling. Preserves r7, r8, r9
+ */
+ .macro arch_irq_handler_default
+1: get_irqnr_and_base r0, r2, r6, lr
+ .endm
--
1.8.3.2

View file

@ -0,0 +1,135 @@
From e9898a39fce7db84ae56329d4f90da92af3bd584 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Wed, 24 Sep 2014 11:57:51 +0100
Subject: [PATCH 091/114] dwc_otg: FIQ support on SMP. Set up FIQ stack and
handler on Core 0 only.
---
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 96 ++++++++++++++--------------
1 file changed, 49 insertions(+), 47 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
index 98e1dc5..4d8dd95 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -397,7 +397,55 @@ static struct fiq_handler fh = {
.name = "usb_fiq",
};
+static void hcd_init_fiq(void *cookie)
+{
+ dwc_otg_device_t *otg_dev = cookie;
+ dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
+ struct pt_regs regs;
+
+ if (claim_fiq(&fh)) {
+ DWC_ERROR("Can't claim FIQ");
+ BUG();
+ }
+ DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
+ DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
+ set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
+ memset(&regs,0,sizeof(regs));
+
+ regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
+ if (fiq_fsm_enable) {
+ regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
+ //regs.ARM_r10 = dwc_otg_hcd->dma;
+ regs.ARM_fp = (long) dwc_otg_fiq_fsm;
+ } else {
+ regs.ARM_fp = (long) dwc_otg_fiq_nop;
+ }
+ regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
+
+// __show_regs(&regs);
+ set_fiq_regs(&regs);
+
+ //Set the mphi periph to the required registers
+ dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
+ dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
+ dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
+ dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
+ dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
+ dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
+ DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
+ //Enable mphi peripheral
+ writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
+#ifdef DEBUG
+ if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
+ DWC_WARN("MPHI periph has been enabled");
+ else
+ DWC_WARN("MPHI periph has NOT been enabled");
+#endif
+ // Enable FIQ interrupt from USB peripheral
+ enable_fiq(INTERRUPT_VC_USB);
+ local_fiq_enable();
+}
/**
* Initializes the HCD. This function allocates memory for and initializes the
@@ -412,7 +460,6 @@ int hcd_init(dwc_bus_dev_t *_dev)
dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
int retval = 0;
u64 dmamask;
- struct pt_regs regs;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
@@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
}
if (fiq_enable)
- {
- if (claim_fiq(&fh)) {
- DWC_ERROR("Can't claim FIQ");
- goto error2;
- }
-
- DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
- DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
-
- set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
- memset(&regs,0,sizeof(regs));
-
- regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
- if (fiq_fsm_enable) {
- regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
- //regs.ARM_r10 = dwc_otg_hcd->dma;
- regs.ARM_fp = (long) dwc_otg_fiq_fsm;
- } else {
- regs.ARM_fp = (long) dwc_otg_fiq_nop;
- }
-
- regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
-
-// __show_regs(&regs);
- set_fiq_regs(&regs);
-
- //Set the mphi periph to the required registers
- dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
- dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
- dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
- dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
- dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
- dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
- DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
- //Enable mphi peripheral
- writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
-#ifdef DEBUG
- if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
- DWC_WARN("MPHI periph has been enabled");
- else
- DWC_WARN("MPHI periph has NOT been enabled");
-#endif
- // Enable FIQ interrupt from USB peripheral
- enable_fiq(INTERRUPT_VC_USB);
- local_fiq_enable();
- }
+ smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
otg_dev->hcd->otg_dev = otg_dev;
--
1.8.3.2

View file

@ -0,0 +1,322 @@
From 424f79f35a94611f73182f19a7711174b756b052 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Fri, 26 Sep 2014 11:32:09 +0100
Subject: [PATCH 092/114] dwc_otg: introduce fiq_fsm_spin(un|)lock()
SMP safety for the FIQ relies on register read-modify write cycles being
completed in the correct order. Several places in the DWC code modify
registers also touched by the FIQ. Protect these by a bare-bones lock
mechanism.
This also makes it possible to run the FIQ and IRQ handlers on different
cores.
---
.../usb/host/dwc_common_port/dwc_common_linux.c | 6 ---
drivers/usb/host/dwc_otg/dwc_otg_cil.c | 10 -----
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 46 +++++++++++++++++++++-
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 16 +++++++-
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 ++++++++++-
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 9 ++++-
6 files changed, 88 insertions(+), 22 deletions(-)
diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
index 5c50a8b..b802042 100644
--- a/drivers/usb/host/dwc_common_port/dwc_common_linux.c
+++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
@@ -580,13 +580,7 @@ void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value)
void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
{
- unsigned long flags;
-
- local_irq_save(flags);
- local_fiq_disable();
writel((readl(reg) & ~clear_mask) | set_mask, reg);
- local_fiq_enable();
- local_irq_restore(flags);
}
#if 0
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
index 6a32c5c..e40060f 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_cil.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
@@ -2244,9 +2244,7 @@ void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
*/
void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
{
- uint32_t intr_enable;
hcintmsk_data_t hc_intr_mask;
- gintmsk_data_t gintmsk = {.d32 = 0 };
hcchar_data_t hcchar;
hcsplt_data_t hcsplt;
@@ -2348,14 +2346,6 @@ void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
}
DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
- /* Enable the top level host channel interrupt. */
- intr_enable = (1 << hc_num);
- DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
-
- /* Make sure host channel interrupts are enabled. */
- gintmsk.b.hcintr = 1;
- DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
-
/*
* Program the HCCHARn register with the endpoint characteristics for
* the current transfer.
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
index 284f902..84618a5 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
@@ -75,6 +75,46 @@ void notrace _fiq_print(enum fiq_debug_level dbg_lvl, volatile struct fiq_state
}
/**
+ * fiq_fsm_spin_lock() - ARMv6+ bare bones spinlock
+ * Must be called with local interrupts and FIQ disabled.
+ */
+inline void fiq_fsm_spin_lock(fiq_lock_t *lock)
+{
+ unsigned long tmp;
+ uint32_t newval;
+ fiq_lock_t lockval;
+ smp_mb__before_spinlock();
+ /* Nested locking, yay. If we are on the same CPU as the fiq, then the disable
+ * will be sufficient. If we are on a different CPU, then the lock protects us. */
+ prefetchw(&lock->slock);
+ asm volatile (
+ "1: ldrex %0, [%3]\n"
+ " add %1, %0, %4\n"
+ " strex %2, %1, [%3]\n"
+ " teq %2, #0\n"
+ " bne 1b"
+ : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
+ : "r" (&lock->slock), "I" (1 << 16)
+ : "cc");
+
+ while (lockval.tickets.next != lockval.tickets.owner) {
+ wfe();
+ lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);
+ }
+ smp_mb();
+}
+
+/**
+ * fiq_fsm_spin_unlock() - ARMv6+ bare bones spinunlock
+ */
+inline void fiq_fsm_spin_unlock(fiq_lock_t *lock)
+{
+ smp_mb();
+ lock->tickets.owner++;
+ dsb_sev();
+}
+
+/**
* fiq_fsm_restart_channel() - Poke channel enable bit for a split transaction
* @channel: channel to re-enable
*/
@@ -1142,6 +1182,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels)
gintsts_handled.d32 = 0;
haint_handled.d32 = 0;
+ fiq_fsm_spin_lock(&state->lock);
gintsts.d32 = FIQ_READ(state->dwc_regs_base + GINTSTS);
gintmsk.d32 = FIQ_READ(state->dwc_regs_base + GINTMSK);
gintsts.d32 &= gintmsk.d32;
@@ -1231,7 +1272,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels)
}
state->fiq_done++;
- mb();
+ fiq_fsm_spin_unlock(&state->lock);
}
@@ -1253,6 +1294,7 @@ void notrace dwc_otg_fiq_nop(struct fiq_state *state)
gintmsk_data_t gintmsk;
hfnum_data_t hfnum;
+ fiq_fsm_spin_lock(&state->lock);
hfnum.d32 = FIQ_READ(state->dwc_regs_base + HFNUM);
gintsts.d32 = FIQ_READ(state->dwc_regs_base + GINTSTS);
gintmsk.d32 = FIQ_READ(state->dwc_regs_base + GINTMSK);
@@ -1290,5 +1332,5 @@ void notrace dwc_otg_fiq_nop(struct fiq_state *state)
}
state->fiq_done++;
- mb();
+ fiq_fsm_spin_unlock(&state->lock);
}
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
index 5c7707f..8455324 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
@@ -120,7 +120,6 @@ typedef struct {
volatile void* intstat;
} mphi_regs_t;
-
enum fiq_debug_level {
FIQDBG_SCHED = (1 << 0),
FIQDBG_INT = (1 << 1),
@@ -128,6 +127,16 @@ enum fiq_debug_level {
FIQDBG_PORTHUB = (1 << 3),
};
+typedef struct {
+ union {
+ uint32_t slock;
+ struct _tickets {
+ uint16_t owner;
+ uint16_t next;
+ } tickets;
+ };
+} fiq_lock_t;
+
struct fiq_state;
extern void _fiq_print (enum fiq_debug_level dbg_lvl, volatile struct fiq_state *state, char *fmt, ...);
@@ -324,6 +333,7 @@ struct fiq_channel_state {
* It contains top-level state information.
*/
struct fiq_state {
+ fiq_lock_t lock;
mphi_regs_t mphi_regs;
void *dwc_regs_base;
dma_addr_t dma_base;
@@ -342,6 +352,10 @@ struct fiq_state {
struct fiq_channel_state channel[0];
};
+extern void fiq_fsm_spin_lock(fiq_lock_t *lock);
+
+extern void fiq_fsm_spin_unlock(fiq_lock_t *lock);
+
extern int fiq_fsm_too_late(struct fiq_state *st, int n);
extern int fiq_fsm_tt_in_use(struct fiq_state *st, int num_channels, int n);
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
index 68d4f3b..124ac16 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
@@ -1184,6 +1184,9 @@ static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
dwc_otg_qtd_t *qtd;
dwc_otg_hcd_urb_t *urb;
void* ptr = NULL;
+ uint32_t intr_enable;
+ unsigned long flags;
+ gintmsk_data_t gintmsk = { .d32 = 0, };
qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
@@ -1409,6 +1412,20 @@ static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
hc->desc_list_addr = qh->desc_list_dma;
dwc_otg_hc_init(hcd->core_if, hc);
+
+ local_irq_save(flags);
+ local_fiq_disable();
+ fiq_fsm_spin_lock(&hcd->fiq_state->lock);
+ /* Enable the top level host channel interrupt. */
+ intr_enable = (1 << hc->hc_num);
+ DWC_MODIFY_REG32(&hcd->core_if->host_if->host_global_regs->haintmsk, 0, intr_enable);
+
+ /* Make sure host channel interrupts are enabled. */
+ gintmsk.b.hcintr = 1;
+ DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
+ fiq_fsm_spin_unlock(&hcd->fiq_state->lock);
+ local_fiq_enable();
+ local_irq_restore(flags);
hc->qh = qh;
}
@@ -1659,6 +1676,7 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hcdma_copy.d32);
hfnum.d32 = DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hfnum);
local_fiq_disable();
+ fiq_fsm_spin_lock(&hcd->fiq_state->lock);
DWC_WRITE_REG32(&hc_regs->hctsiz, st->hctsiz_copy.d32);
DWC_WRITE_REG32(&hc_regs->hcsplt, st->hcsplt_copy.d32);
DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
@@ -1676,6 +1694,7 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
}
mb();
st->hcchar_copy.b.chen = 0;
+ fiq_fsm_spin_unlock(&hcd->fiq_state->lock);
local_fiq_enable();
return 0;
}
@@ -1811,7 +1830,7 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
DWC_WRITE_REG32(&hc_regs->hcintmsk, st->hcintmsk_copy.d32);
local_fiq_disable();
- mb();
+ fiq_fsm_spin_lock(&hcd->fiq_state->lock);
if (hc->ep_type & 0x1) {
hfnum.d32 = DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hfnum);
@@ -1909,7 +1928,7 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
st->hcchar_copy.b.chen = 1;
DWC_WRITE_REG32(&hc_regs->hcchar, st->hcchar_copy.d32);
}
- mb();
+ fiq_fsm_spin_unlock(&hcd->fiq_state->lock);
local_fiq_enable();
return 0;
}
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
index a5566bc..ee35196 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
@@ -101,6 +101,7 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd)
if (dwc_otg_is_host_mode(core_if)) {
if (fiq_enable) {
local_fiq_disable();
+ fiq_fsm_spin_lock(&dwc_otg_hcd->fiq_state->lock);
/* Pull in from the FIQ's disabled mask */
gintmsk.d32 = gintmsk.d32 | ~(dwc_otg_hcd->fiq_state->gintmsk_saved.d32);
dwc_otg_hcd->fiq_state->gintmsk_saved.d32 = ~0;
@@ -116,8 +117,10 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd)
}
gintsts.d32 &= gintmsk.d32;
- if (fiq_enable)
+ if (fiq_enable) {
+ fiq_fsm_spin_unlock(&dwc_otg_hcd->fiq_state->lock);
local_fiq_enable();
+ }
if (!gintsts.d32) {
goto exit_handler_routine;
@@ -200,6 +203,7 @@ exit_handler_routine:
gintmsk_data_t gintmsk_new;
haintmsk_data_t haintmsk_new;
local_fiq_disable();
+ fiq_fsm_spin_lock(&dwc_otg_hcd->fiq_state->lock);
gintmsk_new.d32 = *(volatile uint32_t *)&dwc_otg_hcd->fiq_state->gintmsk_saved.d32;
if(fiq_fsm_enable)
haintmsk_new.d32 = *(volatile uint32_t *)&dwc_otg_hcd->fiq_state->haintmsk_saved.d32;
@@ -222,6 +226,7 @@ exit_handler_routine:
haintmsk.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
/* Re-enable interrupts that the FIQ masked (first time round) */
FIQ_WRITE(dwc_otg_hcd->fiq_state->dwc_regs_base + GINTMSK, gintmsk.d32);
+ fiq_fsm_spin_unlock(&dwc_otg_hcd->fiq_state->lock);
local_fiq_enable();
if ((jiffies / HZ) > last_time) {
@@ -633,8 +638,10 @@ int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd)
{
/* check the mask? */
local_fiq_disable();
+ fiq_fsm_spin_lock(&dwc_otg_hcd->fiq_state->lock);
haint.b2.chint |= ~(dwc_otg_hcd->fiq_state->haintmsk_saved.b2.chint);
dwc_otg_hcd->fiq_state->haintmsk_saved.b2.chint = ~0;
+ fiq_fsm_spin_unlock(&dwc_otg_hcd->fiq_state->lock);
local_fiq_enable();
}
--
1.8.3.2

View file

@ -0,0 +1,48 @@
From e424348e42e85fa0224819055668845710c54887 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Thu, 22 Jan 2015 11:59:41 +0000
Subject: [PATCH 093/114] fiq_fsm: fix build on bcm2708 and bcm2709 platforms
---
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
index 84618a5..0d2b04e 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
@@ -78,6 +78,7 @@ void notrace _fiq_print(enum fiq_debug_level dbg_lvl, volatile struct fiq_state
* fiq_fsm_spin_lock() - ARMv6+ bare bones spinlock
* Must be called with local interrupts and FIQ disabled.
*/
+#ifdef CONFIG_ARCH_BCM2709
inline void fiq_fsm_spin_lock(fiq_lock_t *lock)
{
unsigned long tmp;
@@ -103,16 +104,23 @@ inline void fiq_fsm_spin_lock(fiq_lock_t *lock)
}
smp_mb();
}
+#else
+inline void fiq_fsm_spin_lock(fiq_lock_t *lock) { }
+#endif
/**
* fiq_fsm_spin_unlock() - ARMv6+ bare bones spinunlock
*/
+#ifdef CONFIG_ARCH_BCM2709
inline void fiq_fsm_spin_unlock(fiq_lock_t *lock)
{
smp_mb();
lock->tickets.owner++;
dsb_sev();
}
+#else
+inline void fiq_fsm_spin_unlock(fiq_lock_t *lock) { }
+#endif
/**
* fiq_fsm_restart_channel() - Poke channel enable bit for a split transaction
--
1.8.3.2

View file

@ -0,0 +1,45 @@
From 1e6d3936f120fd4420662850da0c89eb5c3d9f03 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Thu, 22 Jan 2015 17:49:23 +0000
Subject: [PATCH 094/114] dwc_otg: put some barriers back where they should be
for UP
---
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 2 ++
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
index 0d2b04e..276ad0c7 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
@@ -1280,6 +1280,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels)
}
state->fiq_done++;
+ mb();
fiq_fsm_spin_unlock(&state->lock);
}
@@ -1340,5 +1341,6 @@ void notrace dwc_otg_fiq_nop(struct fiq_state *state)
}
state->fiq_done++;
+ mb();
fiq_fsm_spin_unlock(&state->lock);
}
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
index 124ac16..ac70f1d 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
@@ -1928,6 +1928,7 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
st->hcchar_copy.b.chen = 1;
DWC_WRITE_REG32(&hc_regs->hcchar, st->hcchar_copy.d32);
}
+ mb();
fiq_fsm_spin_unlock(&hcd->fiq_state->lock);
local_fiq_enable();
return 0;
--
1.8.3.2

View file

@ -0,0 +1,33 @@
From 4d5ab4e9eb0ae339e8ae87edb0556435cb0bf4b0 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Thu, 22 Jan 2015 18:02:44 +0000
Subject: [PATCH 095/114] mach_bcm2709: Add Mailbox resources to USB driver
---
arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c
index a1058ad..5d73b73 100644
--- a/arch/arm/mach-bcm2709/bcm2709.c
+++ b/arch/arm/mach-bcm2709/bcm2709.c
@@ -338,6 +338,16 @@ static struct resource bcm2708_usb_resources[] = {
.end = IRQ_USB,
.flags = IORESOURCE_IRQ,
},
+ [4] = {
+ .start = ARM_LOCAL_BASE,
+ .end = ARM_LOCAL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [5] = {
+ .start = IRQ_ARM_LOCAL_MAILBOX1,
+ .end = IRQ_ARM_LOCAL_MAILBOX1,
+ .flags = IORESOURCE_IRQ
+ },
};
--
1.8.3.2

View file

@ -0,0 +1,68 @@
From a31e1ba443ff061c4bf4abbac46ca8e197da3f0c Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Thu, 22 Jan 2015 18:45:23 +0000
Subject: [PATCH 096/114] bcm2709/dwc_otg: Setup FIQ on core 1 if >1 core
active
---
arch/arm/mach-bcm2709/armctrl.c | 10 +++++++++-
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 15 +++++++++++----
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c
index 8e69a813..6e3f0f2 100644
--- a/arch/arm/mach-bcm2709/armctrl.c
+++ b/arch/arm/mach-bcm2709/armctrl.c
@@ -89,7 +89,15 @@ static void armctrl_unmask_irq(struct irq_data *d)
};
int i;
if (d->irq >= FIQ_START) {
- unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
+ unsigned int data;
+ if (num_online_cpus() > 1) {
+ data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING));
+ data &= ~0xc;
+ data |= (1 << 2);
+ writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING));
+ }
+ /* Unmask in ARMCTRL block after routing it properly */
+ data = (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
writel(0x80 | data, __io_address(ARM_IRQ_FAST));
} else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) {
#if 1
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
index 4d8dd95..1d28459 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -407,7 +407,9 @@ static void hcd_init_fiq(void *cookie)
DWC_ERROR("Can't claim FIQ");
BUG();
}
- DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
+ DWC_WARN("FIQ on core %d at 0x%08x",
+ smp_processor_id(),
+ (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
memset(&regs,0,sizeof(regs));
@@ -510,9 +512,14 @@ int hcd_init(dwc_bus_dev_t *_dev)
goto error2;
}
- if (fiq_enable)
- smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
-
+ if (fiq_enable) {
+ if (num_online_cpus() > 1) {
+ /* bcm2709: can run the FIQ on a separate core to IRQs */
+ smp_call_function_single(1, hcd_init_fiq, otg_dev, 1);
+ } else {
+ smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
+ }
+ }
otg_dev->hcd->otg_dev = otg_dev;
hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
--
1.8.3.2

Some files were not shown because too many files have changed in this diff Show more