Commit fb4f0424 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 's3c64xx/multiplatform' into next/multiplatform

* s3c64xx/multiplatform:
  ARM: s3c64xx: allow building without board support
  ARM: s3c64xx: multiplatform support
  ARM: s3c64xx: use common debug-ll implementation
  ARM: s3c64xx: use new adc/touchscreen driver
  iio: exynos-adc: add experimental touchscreen support
  ARM: s3c64xx: enable sparse IRQ support
  ARM: s3c64xx: prepare initcalls for multiplatform
  gpio: samsung: move gpio-samsung driver back to platform code
  ASoC: samsung/smartq: use dynamic registration
  Input: s3c2410_ts: fix S3C_ADC dependency

Conflicts:
	arch/arm/Kconfig.debug
parents 35d3aad4 b2821042
......@@ -47,6 +47,9 @@ Required properties:
- samsung,syscon-phandle Contains the PMU system controller node
(To access the ADC_PHY register on Exynos5250/5420/5800/3250)
Optional properties:
- has-touchscreen: If present, indicates that a touchscreen is
connected an usable.
Note: child nodes can be added for auto probing from device tree.
......
......@@ -682,32 +682,6 @@ config ARCH_S3C24XX
(<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
Samsung SMDK2410 development board (and derivatives).
config ARCH_S3C64XX
bool "Samsung S3C64XX"
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
select ATAGS
select CLKDEV_LOOKUP
select CLKSRC_SAMSUNG_PWM
select COMMON_CLK_SAMSUNG
select CPU_V6K
select GENERIC_CLOCKEVENTS
select GPIO_SAMSUNG
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_TCM
select NO_IOPORT_MAP
select PLAT_SAMSUNG
select PM_GENERIC_DOMAINS if PM
select S3C_DEV_NAND
select S3C_GPIO_TRACK
select SAMSUNG_ATAGS
select SAMSUNG_WAKEMASK
select SAMSUNG_WDT_RESET
help
Samsung S3C64XX series based systems
config ARCH_DAVINCI
bool "TI DaVinci"
select ARCH_HAS_HOLES_MEMORYMODEL
......
......@@ -914,6 +914,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 0 for low-level debug"
help
......@@ -925,6 +926,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 1 for low-level debug"
help
......@@ -936,6 +938,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 2 for low-level debug"
help
......@@ -946,6 +949,7 @@ choice
config DEBUG_S3C_UART3
depends on PLAT_SAMSUNG && (ARCH_EXYNOS || ARCH_S5PV210)
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 3 for low-level debug"
help
......@@ -1320,6 +1324,9 @@ config DEBUG_S3C2410_UART
config DEBUG_S3C24XX_UART
bool
config DEBUG_S3C64XX_UART
bool
config DEBUG_S5PV210_UART
bool
......@@ -1406,7 +1413,7 @@ config DEBUG_LL_INCLUDE
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART || DEBUG_S3C64XX_UART
default "debug/s5pv210.S" if DEBUG_S5PV210_UART
default "debug/sirf.S" if DEBUG_SIRFSOC_UART
default "debug/sti.S" if DEBUG_STI_UART
......@@ -1482,6 +1489,10 @@ config DEBUG_UART_PHYS
DEBUG_S3C2410_UART2)
default 0x78000000 if DEBUG_CNS3XXX
default 0x7c0003f8 if DEBUG_FOOTBRIDGE_COM1
default 0x7f005000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
default 0x7f005400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
default 0x7f005800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
default 0x7f005c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
default 0x80010000 if DEBUG_ASM9260_UART
default 0x80070000 if DEBUG_IMX23_UART
default 0x80074000 if DEBUG_IMX28_UART
......@@ -1538,6 +1549,7 @@ config DEBUG_UART_PHYS
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
DEBUG_S3C64XX_UART || \
DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
DEBUG_AT91_UART
......@@ -1564,8 +1576,12 @@ config DEBUG_UART_VIRT
default 0xf4200000 if DEBUG_GEMINI
default 0xf6200000 if DEBUG_PXA_UART1
default 0xf7000000 if DEBUG_SUN9I_UART0
default 0xf7000000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
DEBUG_S3C2410_UART0)
default 0xf7000400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
default 0xf7000800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
default 0xf7000c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
DEBUG_S3C2410_UART1)
default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
......@@ -1629,6 +1645,7 @@ config DEBUG_UART_VIRT
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
DEBUG_S3C64XX_UART || \
DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
......
......@@ -11,6 +11,9 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CMDLINE_PARTITION=y
CONFIG_ARCH_MULTI_V7=y
# CONFIG_ARCH_MULTI_V5 is not set
# CONFIG_ARCH_MULTI_V4 is not set
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_ALPINE=y
CONFIG_ARCH_MVEBU=y
......
......@@ -5,6 +5,8 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_MULTI_V6=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_S3C64XX=y
CONFIG_S3C_BOOT_ERROR_RESET=y
CONFIG_MACH_SMDK6400=y
......
......@@ -2,6 +2,26 @@
# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
#
# Licensed under GPLv2
menuconfig ARCH_S3C64XX
bool "Samsung S3C64XX" if ARCH_MULTI_V6
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
select CLKSRC_SAMSUNG_PWM
select COMMON_CLK_SAMSUNG
select GPIO_SAMSUNG if ATAGS
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_TCM
select PLAT_SAMSUNG
select PM_GENERIC_DOMAINS if PM
select S3C_DEV_NAND if ATAGS
select S3C_GPIO_TRACK if ATAGS
select SAMSUNG_ATAGS if ATAGS
select SAMSUNG_WAKEMASK if PM
select SAMSUNG_WDT_RESET
help
Samsung S3C64XX series based systems
if ARCH_S3C64XX
......@@ -90,6 +110,7 @@ config S3C64XX_SETUP_USB_PHY
config MACH_SMDK6400
bool "SMDK6400"
depends on ATAGS
select CPU_S3C6400
select S3C64XX_SETUP_SDHCI
select S3C_DEV_HSMMC1
......@@ -100,6 +121,7 @@ config MACH_SMDK6400
config MACH_ANW6410
bool "A&W6410"
depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_FB
......@@ -108,6 +130,7 @@ config MACH_ANW6410
config MACH_MINI6410
bool "MINI6410"
depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_SDHCI
......@@ -123,6 +146,7 @@ config MACH_MINI6410
config MACH_REAL6410
bool "REAL6410"
depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_SDHCI
......@@ -138,6 +162,7 @@ config MACH_REAL6410
config MACH_SMDK6410
bool "SMDK6410"
depends on ATAGS
select CPU_S3C6410
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select S3C64XX_SETUP_FB_24BPP
......@@ -225,6 +250,7 @@ config SMDK6410_WM1192_EV1
config MACH_NCP
bool "NCP"
depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_I2C1
select S3C_DEV_HSMMC1
......@@ -234,6 +260,7 @@ config MACH_NCP
config MACH_HMT
bool "Airgoo HMT"
depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_FB
......@@ -265,18 +292,21 @@ config MACH_SMARTQ
config MACH_SMARTQ5
bool "SmartQ 5"
depends on ATAGS
select MACH_SMARTQ
help
Machine support for the SmartQ 5
config MACH_SMARTQ7
bool "SmartQ 7"
depends on ATAGS
select MACH_SMARTQ
help
Machine support for the SmartQ 7
config MACH_WLF_CRAGG_6410
bool "Wolfson Cragganmore 6410"
depends on ATAGS
depends on I2C=y
select CPU_S3C6410
select LEDS_GPIO_REGISTER
......@@ -310,7 +340,6 @@ config MACH_S3C64XX_DT
select CPU_S3C6410
select PINCTRL
select PINCTRL_S3C64XX
select USE_OF
help
Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
enabled.
......
......@@ -5,21 +5,25 @@
#
# Licensed under GPLv2
# Core
obj-y += common.o
# Core support
obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
# PM
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
obj-$(CONFIG_PM_SLEEP) += sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
ifdef CONFIG_SAMSUNG_ATAGS
obj-$(CONFIG_PM_SLEEP) += irq-pm.o
# Core
obj-y += common.o
obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
# DMA support
obj-$(CONFIG_S3C64XX_PL080) += pl080.o
......@@ -55,4 +59,6 @@ obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o
obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
endif
obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o
......@@ -39,6 +39,7 @@
#include <asm/system_misc.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
......@@ -208,7 +209,7 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
static __init int s3c64xx_dev_init(void)
{
/* Not applicable when using DT. */
if (of_have_populated_dt())
if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
subsys_system_register(&s3c64xx_subsys, NULL);
......@@ -413,7 +414,7 @@ static int __init s3c64xx_init_irq_eint(void)
int irq;
/* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
if (of_have_populated_dt())
if (of_have_populated_dt() || !soc_is_s3c64xx())
return -ENODEV;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
......
......@@ -18,6 +18,7 @@
#include <asm/cpuidle.h>
#include <plat/cpu.h>
#include <mach/map.h>
#include "regs-sys.h"
......@@ -57,6 +58,8 @@ static struct cpuidle_driver s3c64xx_cpuidle_driver = {
static int __init s3c64xx_init_cpuidle(void)
{
if (soc_is_s3c64xx())
return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
return 0;
}
device_initcall(s3c64xx_init_cpuidle);
......@@ -23,6 +23,7 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/devs.h>
......
/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* 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.
*/
/* pull in the relevant register and map files. */
#include <linux/serial_s3c.h>
#include <mach/map.h>
/* note, for the boot process to work we have to keep the UART
* virtual address aligned to an 1MiB boundary for the L1
* mapping the head code makes. We keep the UART virtual address
* aligned and add in the offset when we load the value here.
*/
.macro addruart, rp, rv, tmp
ldr \rp, = S3C_PA_UART
ldr \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
#if CONFIG_DEBUG_S3C_UART != 0
add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
/* include the reset of the code which will do the work, we're only
* compiling for a single cpu processor type so the default of s3c2440
* will be fine with us.
*/
#include <debug/samsung.S>
......@@ -14,6 +14,8 @@
#ifndef GPIO_SAMSUNG_S3C64XX_H
#define GPIO_SAMSUNG_S3C64XX_H
#ifdef CONFIG_GPIO_SAMSUNG
/* GPIO bank sizes */
#define S3C64XX_GPIO_A_NR (8)
#define S3C64XX_GPIO_B_NR (7)
......@@ -90,5 +92,6 @@ enum s3c_gpio_number {
/* define the number of gpios we need to the one after the GPQ() range */
#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
#endif /* GPIO_SAMSUNG */
#endif /* GPIO_SAMSUNG_S3C64XX_H */
......@@ -156,25 +156,11 @@
#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
/* Define a group of interrupts for board-specific use (eg, for MFD
* interrupt controllers). */
/* Some boards have their own IRQs behind this */
#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
#ifdef CONFIG_MACH_WLF_CRAGG_6410
#define IRQ_BOARD_NR 160
#elif defined(CONFIG_SMDK6410_WM1190_EV1)
#define IRQ_BOARD_NR 64
#elif defined(CONFIG_SMDK6410_WM1192_EV1)
#define IRQ_BOARD_NR 64
#else
#define IRQ_BOARD_NR 16
#endif
#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
/* Set the default NR_IRQS */
#define NR_IRQS (IRQ_BOARD_END + 1)
/* Set the default nr_irqs, boards can override if necessary */
#define S3C64XX_NR_IRQS IRQ_BOARD_START
/* Compatibility */
......
......@@ -18,6 +18,7 @@
#include <linux/serial_s3c.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
static inline void s3c_pm_debug_init_uart(void)
{
......
......@@ -113,7 +113,7 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = {
static __init int s3c64xx_syscore_init(void)
{
/* Appropriate drivers (pinctrl, uart) handle this when using DT. */
if (of_have_populated_dt())
if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
register_syscore_ops(&s3c64xx_irq_syscore_ops);
......
......@@ -47,6 +47,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <mach/irqs.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/samsung-time.h>
......@@ -229,7 +230,7 @@ static void __init anw6410_machine_init(void)
MACHINE_START(ANW6410, "A&W6410")
/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = anw6410_map_io,
.init_machine = anw6410_machine_init,
......
......@@ -29,6 +29,9 @@
#include <linux/platform_data/spi-s3c64xx.h>
#include <plat/cpu.h>
#include <mach/irqs.h>
#include "crag6410.h"
static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
......@@ -399,6 +402,9 @@ static struct i2c_driver wlf_gf_module_driver = {
static int __init wlf_gf_module_register(void)
{
if (!soc_is_s3c64xx())
return 0;
return i2c_add_driver(&wlf_gf_module_driver);
}
device_initcall(wlf_gf_module_register);
......@@ -52,6 +52,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <mach/irqs.h>
#include <plat/fb.h>
#include <plat/sdhci.h>
......@@ -860,6 +861,7 @@ static void __init crag6410_machine_init(void)
MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
/* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = crag6410_map_io,
.init_machine = crag6410_machine_init,
......
......@@ -31,6 +31,7 @@
#include <video/samsung_fimd.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
......@@ -279,6 +280,7 @@ static void __init hmt_machine_init(void)
MACHINE_START(HMT, "Airgoo-HMT")
/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = hmt_map_io,
.init_machine = hmt_machine_init,
......
......@@ -41,6 +41,7 @@
#include <linux/platform_data/mmc-sdhci-s3c.h>
#include <plat/sdhci.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <mach/irqs.h>
#include <video/platform_lcd.h>
#include <video/samsung_fimd.h>
......@@ -233,7 +234,6 @@ static struct platform_device *mini6410_devices[] __initdata = {
&s3c_device_fb,
&mini6410_lcd_powerdev,
&s3c_device_adc,
&s3c_device_ts,
};
static void __init mini6410_map_io(void)
......@@ -332,7 +332,7 @@ static void __init mini6410_machine_init(void)
s3c_nand_set_platdata(&mini6410_nand_info);
s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]);
s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);
s3c24xx_ts_set_platdata(NULL);
s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
......@@ -363,6 +363,7 @@ static void __init mini6410_machine_init(void)
MACHINE_START(MINI6410, "MINI6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = mini6410_map_io,
.init_machine = mini6410_machine_init,
......
......@@ -31,6 +31,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/map.h>
......@@ -100,6 +101,7 @@ static void __init ncp_machine_init(void)
MACHINE_START(NCP, "NCP")
/* Maintainer: Samsung Electronics */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = ncp_map_io,
.init_machine = ncp_machine_init,
......
......@@ -33,6 +33,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <mach/irqs.h>
#include <plat/adc.h>
#include <plat/cpu.h>
......@@ -202,7 +203,6 @@ static struct platform_device *real6410_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_nand,
&s3c_device_adc,
&s3c_device_ts,
&s3c_device_ohci,
};
......@@ -301,7 +301,7 @@ static void __init real6410_machine_init(void)
s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
s3c_nand_set_platdata(&real6410_nand_info);
s3c24xx_ts_set_platdata(NULL);
s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
......@@ -331,7 +331,7 @@ static void __init real6410_machine_init(void)
MACHINE_START(REAL6410, "REAL6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = real6410_map_io,
.init_machine = real6410_machine_init,
......
......@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
......@@ -252,7 +253,6 @@ static struct platform_device *smartq_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_rtc,
&samsung_device_pwm,
&s3c_device_ts,
&s3c_device_usb_hsotg,
&s3c64xx_device_iis0,
&smartq_backlight_device,
......@@ -383,6 +383,15 @@ void __init smartq_map_io(void)
smartq_lcd_mode_set();
}
static struct gpiod_lookup_table smartq_audio_gpios = {
.dev_id = "smartq-audio",
.table = {
GPIO_LOOKUP("GPL", 12, "headphone detect", 0),
GPIO_LOOKUP("GPK", 12, "amplifiers shutdown", 0),
{ },
},
};
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
......@@ -390,7 +399,7 @@ void __init smartq_machine_init(void)
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
s3c24xx_ts_set_platdata(&smartq_touchscreen_pdata);
s3c64xx_ts_set_platdata(&smartq_touchscreen_pdata);
i2c_register_board_info(0, smartq_i2c_devs,
ARRAY_SIZE(smartq_i2c_devs));
......@@ -402,4 +411,7 @@ void __init smartq_machine_init(void)
pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
gpiod_add_lookup_table(&smartq_audio_gpios);
platform_device_register_simple("smartq-audio", -1, NULL, 0);
}
......@@ -21,6 +21,7 @@
#include <asm/mach/arch.h>
#include <video/samsung_fimd.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
......@@ -153,6 +154,7 @@ static void __init smartq5_machine_init(void)
MACHINE_START(SMARTQ5, "SmartQ 5")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
.init_machine = smartq5_machine_init,
......
......@@ -21,6 +21,7 @@
#include <asm/mach/arch.h>
#include <video/samsung_fimd.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
......@@ -169,6 +170,7 @@ static void __init smartq7_machine_init(void)
MACHINE_START(SMARTQ7, "SmartQ 7")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
.init_machine = smartq7_machine_init,
......
......@@ -27,6 +27,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/map.h>
......@@ -88,7 +89,7 @@ static void __init smdk6400_machine_init(void)
MACHINE_START(SMDK6400, "SMDK6400")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6400_init_irq,
.map_io = smdk6400_map_io,
.init_machine = smdk6400_machine_init,
......
......@@ -52,6 +52,7 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <asm/irq.h>
......@@ -289,7 +290,6 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
&s3c_device_rtc,
&s3c_device_ts,
&s3c_device_wdt,
};
......@@ -668,7 +668,7 @@ static void __init smdk6410_machine_init(void)
samsung_keypad_set_platdata(&smdk6410_keypad_data);
s3c24xx_ts_set_platdata(NULL);
s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
......@@ -707,7 +707,7 @@ static void __init smdk6410_machine_init(void)
MACHINE_START(SMDK6410, "SMDK6410")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
.atag_offset = 0x100,
.nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smdk6410_map_io,
.init_machine = smdk6410_machine_init,
......
......@@ -14,6 +14,7 @@
#include <linux/amba/pl08x.h>
#include <linux/of.h>
#include <plat/cpu.h>
#include <mach/irqs.h>
#include <mach/map.h>
......@@ -230,6 +231,9 @@ static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
static int __init s3c64xx_pl080_init(void)
{
if (!soc_is_s3c64xx())
return 0;
/* Set all DMA configuration to be DMA, not SDMA */
writel(0xffffff, S3C64XX_SDMA_SEL);
......
......@@ -22,6 +22,7 @@
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/wakeup-mask.h>
......@@ -332,6 +333,9 @@ int __init s3c64xx_pm_init(void)
static __init int s3c64xx_pm_initcall(void)
{
if (!soc_is_s3c64xx())
return 0;
pm_cpu_prep = s3c64xx_pm_prepare;
pm_cpu_sleep = s3c64xx_cpu_suspend;
......
......@@ -81,7 +81,7 @@ static struct device s3c6400_dev = {
static int __init s3c6400_core_init(void)
{
/* Not applicable when using DT. */
if (of_have_populated_dt())
if (of_have_populated_dt() || soc_is_s3c64xx())
return 0;
return subsys_system_register(&s3c6400_subsys, NULL);
......
......@@ -84,7 +84,7 @@ static struct device s3c6410_dev = {
static int __init s3c6410_core_init(void)
{
/* Not applicable when using DT. */
if (of_have_populated_dt())
if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
return subsys_system_register(&s3c6410_subsys, NULL);
......
......@@ -39,7 +39,6 @@ config S3C_LOWLEVEL_UART_PORT
config SAMSUNG_ATAGS
def_bool n
depends on !ARCH_MULTIPLATFORM
depends on ATAGS
help
This option enables ATAGS based boot support code for
......@@ -70,6 +69,7 @@ config S3C_GPIO_TRACK
config S3C_ADC
bool "ADC common driver support"
depends on !ARCH_MULTIPLATFORM
help
Core support for the ADC block found in the Samsung SoC systems
for drivers such as the touchscreen and hwmon to use to share
......@@ -225,6 +225,9 @@ config S3C24XX_PWM
Support for exporting the PWM timer blocks via the pwm device
system
config GPIO_SAMSUNG
def_bool y
config SAMSUNG_PM_GPIO
bool
default y if GPIO_SAMSUNG && PM
......
......@@ -4,7 +4,8 @@
#
# Licensed under GPLv2
ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include
ccflags-$(CONFIG_ARCH_S3C64XX) := -I$(srctree)/arch/arm/mach-s3c64xx/include
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include
# Objects we always build independent of SoC choice
......@@ -21,6 +22,8 @@ obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o
obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o
obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o
obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o
# PM support
obj-$(CONFIG_PM_SLEEP) += pm-common.o
......
......@@ -111,12 +111,12 @@ struct platform_device s3c_device_adc = {
#if defined(CONFIG_SAMSUNG_DEV_ADC)
static struct resource s3c_adc_resource[] = {
[0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
[1] = DEFINE_RES_IRQ(IRQ_TC),
[2] = DEFINE_RES_IRQ(IRQ_ADC),
[1] = DEFINE_RES_IRQ(IRQ_ADC),
[2] = DEFINE_RES_IRQ(IRQ_TC),
};
struct platform_device s3c_device_adc = {
.name = "samsung-adc",
.name = "exynos-adc",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_adc_resource),
.resource = s3c_adc_resource,
......@@ -939,31 +939,19 @@ void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_
#endif /* CONFIG_PLAT_S3C24XX */
#ifdef CONFIG_SAMSUNG_DEV_TS
static struct resource s3c_ts_resource[] = {
[0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
[1] = DEFINE_RES_IRQ(IRQ_TC),
};
static struct s3c2410_ts_mach_info default_ts_data __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
struct platform_device s3c_device_ts = {
.name = "s3c64xx-ts",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_ts_resource),
.resource = s3c_ts_resource,
};
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
{
if (!pd)
pd = &default_ts_data;
s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
&s3c_device_ts);
&s3c_device_adc);
}
#endif /* CONFIG_SAMSUNG_DEV_TS */
......
......@@ -30,6 +30,7 @@
#include <asm/irq.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
......@@ -1176,14 +1177,16 @@ static __init int samsung_gpiolib_init(void)
* interfaces. For legacy (non-DT) platforms this driver is used.
*/
if (of_have_populated_dt())
return -ENODEV;
samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
return 0;
if (soc_is_s3c24xx()) {
samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
ARRAY_SIZE(samsung_gpio_cfgs));
s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
} else if (soc_is_s3c64xx()) {
samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
ARRAY_SIZE(samsung_gpio_cfgs));
samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
ARRAY_SIZE(s3c64xx_gpios_2bit),
S3C64XX_VA_GPIO + 0xE0, 0x20);
......@@ -1192,9 +1195,6 @@ static __init int samsung_gpiolib_init(void)
S3C64XX_VA_GPIO);
samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
ARRAY_SIZE(s3c64xx_gpios_4bit2));
} else {
WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
return -ENODEV;
}
return 0;
......
......@@ -152,6 +152,11 @@ static int __init s3c_arch_init(void)
{
int ret;
/* init is only needed for ATAGS based platforms */
if (!IS_ENABLED(CONFIG_ATAGS) ||
(!soc_is_s3c24xx() && !soc_is_s3c64xx()))
return 0;
// do the correct init for cpu
if (cpu == NULL) {
......
......@@ -23,14 +23,10 @@
#include <asm/cacheflush.h>
#include <asm/suspend.h>
#ifdef CONFIG_SAMSUNG_ATAGS
#include <mach/map.h>
#ifndef CONFIG_ARCH_EXYNOS
#include <mach/regs-clock.h>
#include <mach/regs-irq.h>
#endif
#include <mach/irqs.h>
#endif
#include <asm/irq.h>
......
......@@ -344,13 +344,6 @@ config GPIO_RCAR
help
Say yes here to support GPIO on Renesas R-Car SoCs.
config GPIO_SAMSUNG
bool
depends on PLAT_SAMSUNG
help
Legacy GPIO support. Use only for platforms without support for
pinctrl.
config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
......
......@@ -79,7 +79,6 @@ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
......
......@@ -35,6 +35,7 @@
#include <linux/regulator/consumer.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/input.h>
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
......@@ -42,12 +43,18 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
/* S3C/EXYNOS4412/5250 ADC_V1 registers definitions */
#define ADC_V1_CON(x) ((x) + 0x00)
#define ADC_V1_TSC(x) ((x) + 0x04)
#define ADC_V1_DLY(x) ((x) + 0x08)
#define ADC_V1_DATX(x) ((x) + 0x0C)
#define ADC_V1_DATY(x) ((x) + 0x10)
#define ADC_V1_UPDN(x) ((x) + 0x14)
#define ADC_V1_INTCLR(x) ((x) + 0x18)
#define ADC_V1_MUX(x) ((x) + 0x1c)
#define ADC_V1_CLRINTPNDNUP(x) ((x) + 0x20)
/* S3C2410 ADC registers definitions */
#define ADC_S3C2410_MUX(x) ((x) + 0x18)
......@@ -71,6 +78,30 @@
#define ADC_S3C2410_DATX_MASK 0x3FF
#define ADC_S3C2416_CON_RES_SEL (1u << 3)
/* touch screen always uses channel 0 */
#define ADC_S3C2410_MUX_TS 0
/* ADCTSC Register Bits */
#define ADC_S3C2443_TSC_UD_SEN (1u << 8)
#define ADC_S3C2410_TSC_YM_SEN (1u << 7)
#define ADC_S3C2410_TSC_YP_SEN (1u << 6)
#define ADC_S3C2410_TSC_XM_SEN (1u << 5)
#define ADC_S3C2410_TSC_XP_SEN (1u << 4)
#define ADC_S3C2410_TSC_PULL_UP_DISABLE (1u << 3)
#define ADC_S3C2410_TSC_AUTO_PST (1u << 2)
#define ADC_S3C2410_TSC_XY_PST(x) (((x) & 0x3) << 0)
#define ADC_TSC_WAIT4INT (ADC_S3C2410_TSC_YM_SEN | \
ADC_S3C2410_TSC_YP_SEN | \
ADC_S3C2410_TSC_XP_SEN | \
ADC_S3C2410_TSC_XY_PST(3))
#define ADC_TSC_AUTOPST (ADC_S3C2410_TSC_YM_SEN | \
ADC_S3C2410_TSC_YP_SEN | \
ADC_S3C2410_TSC_XP_SEN | \
ADC_S3C2410_TSC_AUTO_PST | \
ADC_S3C2410_TSC_XY_PST(0))
/* Bit definitions for ADC_V2 */
#define ADC_V2_CON1_SOFT_RESET (1u << 2)
......@@ -88,7 +119,9 @@
/* Bit definitions common for ADC_V1 and ADC_V2 */
#define ADC_CON_EN_START (1u << 0)
#define ADC_CON_EN_START_MASK (0x3 << 0)
#define ADC_DATX_PRESSED (1u << 15)
#define ADC_DATX_MASK 0xFFF
#define ADC_DATY_MASK 0xFFF
#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100))
......@@ -98,17 +131,24 @@
struct exynos_adc {
struct exynos_adc_data *data;
struct device *dev;
struct input_dev *input;
void __iomem *regs;
struct regmap *pmu_map;
struct clk *clk;
struct clk *sclk;
unsigned int irq;
unsigned int tsirq;
unsigned int delay;
struct regulator *vdd;
struct completion completion;
u32 value;
unsigned int version;
bool read_ts;
u32 ts_x;
u32 ts_y;
};
struct exynos_adc_data {
......@@ -197,6 +237,9 @@ static void exynos_adc_v1_init_hw(struct exynos_adc *info)
/* Enable 12-bit ADC resolution */
con1 |= ADC_V1_CON_RES;
writel(con1, ADC_V1_CON(info->regs));
/* set touchscreen delay */
writel(info->delay, ADC_V1_DLY(info->regs));
}
static void exynos_adc_v1_exit_hw(struct exynos_adc *info)
......@@ -480,8 +523,8 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
if (info->data->start_conv)
info->data->start_conv(info, chan->address);
timeout = wait_for_completion_timeout
(&info->completion, EXYNOS_ADC_TIMEOUT);
timeout = wait_for_completion_timeout(&info->completion,
EXYNOS_ADC_TIMEOUT);
if (timeout == 0) {
dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
if (info->data->init_hw)
......@@ -498,13 +541,55 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
return ret;
}
static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
{
struct exynos_adc *info = iio_priv(indio_dev);
unsigned long timeout;
int ret;
mutex_lock(&indio_dev->mlock);
info->read_ts = true;
reinit_completion(&info->completion);
writel(ADC_S3C2410_TSC_PULL_UP_DISABLE | ADC_TSC_AUTOPST,
ADC_V1_TSC(info->regs));
/* Select the ts channel to be used and Trigger conversion */
info->data->start_conv(info, ADC_S3C2410_MUX_TS);
timeout = wait_for_completion_timeout(&info->completion,
EXYNOS_ADC_TIMEOUT);
if (timeout == 0) {
dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
if (info->data->init_hw)
info->data->init_hw(info);
ret = -ETIMEDOUT;
} else {
*x = info->ts_x;
*y = info->ts_y;
ret = 0;
}
info->read_ts = false;
mutex_unlock(&indio_dev->mlock);
return ret;
}
static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
{
struct exynos_adc *info = (struct exynos_adc *)dev_id;
u32 mask = info->data->mask;
/* Read value */
if (info->read_ts) {
info->ts_x = readl(ADC_V1_DATX(info->regs));
info->ts_y = readl(ADC_V1_DATY(info->regs));
writel(ADC_TSC_WAIT4INT | ADC_S3C2443_TSC_UD_SEN, ADC_V1_TSC(info->regs));
} else {
info->value = readl(ADC_V1_DATX(info->regs)) & mask;
}
/* clear irq */
if (info->data->clear_irq)
......@@ -515,6 +600,46 @@ static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
/*
* Here we (ab)use a threaded interrupt handler to stay running
* for as long as the touchscreen remains pressed, we report
* a new event with the latest data and then sleep until the
* next timer tick. This mirrors the behavior of the old
* driver, with much less code.
*/
static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
{
struct exynos_adc *info = dev_id;
struct iio_dev *dev = dev_get_drvdata(info->dev);
u32 x, y;
bool pressed;
int ret;
while (info->input->users) {
ret = exynos_read_s3c64xx_ts(dev, &x, &y);
if (ret == -ETIMEDOUT)
break;
pressed = x & y & ADC_DATX_PRESSED;
if (!pressed) {
input_report_key(info->input, BTN_TOUCH, 0);
input_sync(info->input);
break;
}
input_report_abs(info->input, ABS_X, x & ADC_DATX_MASK);
input_report_abs(info->input, ABS_Y, y & ADC_DATY_MASK);
input_report_key(info->input, BTN_TOUCH, 1);
input_sync(info->input);
msleep(1);
};
writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
return IRQ_HANDLED;
}
static int exynos_adc_reg_access(struct iio_dev *indio_dev,
unsigned reg, unsigned writeval,
unsigned *readval)
......@@ -566,18 +691,72 @@ static int exynos_adc_remove_devices(struct device *dev, void *c)
return 0;
}
static int exynos_adc_ts_open(struct input_dev *dev)
{
struct exynos_adc *info = input_get_drvdata(dev);
enable_irq(info->tsirq);
return 0;
}
static void exynos_adc_ts_close(struct input_dev *dev)
{
struct exynos_adc *info = input_get_drvdata(dev);
disable_irq(info->tsirq);
}
static int exynos_adc_ts_init(struct exynos_adc *info)
{
int ret;
if (info->tsirq <= 0)
return -ENODEV;
info->input = input_allocate_device();
if (!info->input)
return -ENOMEM;
info->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
info->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(info->input, ABS_X, 0, 0x3FF, 0, 0);
input_set_abs_params(info->input, ABS_Y, 0, 0x3FF, 0, 0);
info->input->name = "S3C24xx TouchScreen";
info->input->id.bustype = BUS_HOST;
info->input->open = exynos_adc_ts_open;
info->input->close = exynos_adc_ts_close;
input_set_drvdata(info->input, info);
ret = input_register_device(info->input);
if (ret) {
input_free_device(info->input);
return ret;
}
disable_irq(info->tsirq);
ret = request_threaded_irq(info->tsirq, NULL, exynos_ts_isr,
0, "touchscreen", info);
if (ret)
input_unregister_device(info->input);
return ret;
}
static int exynos_adc_probe(struct platform_device *pdev)
{
struct exynos_adc *info = NULL;
struct device_node *np = pdev->dev.of_node;
struct s3c2410_ts_mach_info *pdata = dev_get_platdata(&pdev->dev);
struct iio_dev *indio_dev = NULL;
struct resource *mem;
bool has_ts = false;
int ret = -ENODEV;
int irq;
if (!np)
return ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
......@@ -613,8 +792,14 @@ static int exynos_adc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no irq resource?\n");
return irq;
}
info->irq = irq;
irq = platform_get_irq(pdev, 1);
if (irq == -EPROBE_DEFER)
return irq;
info->tsirq = irq;
info->dev = &pdev->dev;
init_completion(&info->completion);
......@@ -680,6 +865,22 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (info->data->init_hw)
info->data->init_hw(info);
/* leave out any TS related code if unreachable */
if (IS_REACHABLE(CONFIG_INPUT)) {
has_ts = of_property_read_bool(pdev->dev.of_node,
"has-touchscreen") || pdata;
}
if (pdata)
info->delay = pdata->delay;
else
info->delay = 10000;
if (has_ts)
ret = exynos_adc_ts_init(info);
if (ret)
goto err_iio;
ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "failed adding child nodes\n");
......@@ -691,6 +892,11 @@ static int exynos_adc_probe(struct platform_device *pdev)
err_of_populate:
device_for_each_child(&indio_dev->dev, NULL,
exynos_adc_remove_devices);
if (has_ts) {
input_unregister_device(info->input);
free_irq(info->tsirq, info);
}
err_iio:
iio_device_unregister(indio_dev);
err_irq:
free_irq(info->irq, info);
......@@ -710,6 +916,10 @@ static int exynos_adc_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct exynos_adc *info = iio_priv(indio_dev);
if (IS_REACHABLE(CONFIG_INPUT)) {
free_irq(info->tsirq, info);
input_unregister_device(info->input);
}
device_for_each_child(&indio_dev->dev, NULL,
exynos_adc_remove_devices);
iio_device_unregister(indio_dev);
......
......@@ -365,7 +365,7 @@ config TOUCHSCREEN_IPROC
config TOUCHSCREEN_S3C2410
tristate "Samsung S3C2410/generic touchscreen input driver"
depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
select S3C_ADC
depends on S3C_ADC
help
Say Y here if you have the s3c2410 touchscreen.
......
......@@ -17,6 +17,7 @@ struct s3c2410_ts_mach_info {
};
extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
extern void s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
/* defined by architecture to configure gpio */
extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
......
......@@ -13,15 +13,12 @@
*
*/
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <mach/gpio-samsung.h>
#include <asm/mach-types.h>
#include "i2s.h"
#include "../codecs/wm8750.h"
......@@ -96,7 +93,7 @@ static struct snd_soc_jack_pin smartq_jack_pins[] = {
static struct snd_soc_jack_gpio smartq_jack_gpios[] = {
{
.gpio = S3C64XX_GPL(12),
.gpio = -1,
.name = "headphone detect",
.report = SND_JACK_HEADPHONE,
.debounce_time = 200,
......@@ -113,7 +110,9 @@ static int smartq_speaker_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k,
int event)
{
gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event));
struct gpio_desc *gpio = snd_soc_card_get_drvdata(&snd_soc_smartq);
gpiod_set_value(gpio, SND_SOC_DAPM_EVENT_OFF(event));
return 0;
}
......@@ -199,62 +198,39 @@ static struct snd_soc_card snd_soc_smartq = {
.num_controls = ARRAY_SIZE(wm8987_smartq_controls),
};
static struct platform_device *smartq_snd_device;
static int __init smartq_init(void)
static int smartq_probe(struct platform_device *pdev)
{
struct gpio_desc *gpio;
int ret;
if (!machine_is_smartq7() && !machine_is_smartq5()) {
pr_info("Only SmartQ is supported by this ASoC driver\n");
return -ENODEV;
}
smartq_snd_device = platform_device_alloc("soc-audio", -1);
if (!smartq_snd_device)
return -ENOMEM;
platform_set_drvdata(smartq_snd_device, &snd_soc_smartq);
ret = platform_device_add(smartq_snd_device);
if (ret) {
platform_device_put(smartq_snd_device);
return ret;
}
platform_set_drvdata(pdev, &snd_soc_smartq);
/* Initialise GPIOs used by amplifiers */
ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown");
if (ret) {
dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n");
goto err_unregister_device;
gpio = devm_gpiod_get(&pdev->dev, "amplifiers shutdown",
GPIOD_OUT_HIGH);
if (IS_ERR(gpio)) {
dev_err(&pdev->dev, "Failed to register GPK12\n");
ret = PTR_ERR(gpio);
goto out;
}
snd_soc_card_set_drvdata(&snd_soc_smartq, gpio);
/* Disable amplifiers */
ret = gpio_direction_output(S3C64XX_GPK(12), 1);
if (ret) {
dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n");
goto err_free_gpio_amp_shut;
}
return 0;
err_free_gpio_amp_shut:
gpio_free(S3C64XX_GPK(12));
err_unregister_device:
platform_device_unregister(smartq_snd_device);
ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_smartq);
if (ret)
dev_err(&pdev->dev, "Failed to register card\n");
out:
return ret;
}
static void __exit smartq_exit(void)
{
gpio_free(S3C64XX_GPK(12));
platform_device_unregister(smartq_snd_device);
}
static struct platform_driver smartq_driver = {
.driver = {
.name = "smartq-audio",
},
.probe = smartq_probe,
};
module_init(smartq_init);
module_exit(smartq_exit);
module_platform_driver(smartq_driver);
/* Module information */
MODULE_AUTHOR("Maurus Cuelenaere <mcuelenaere@gmail.com>");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment