From 18c55cd466c12ede49638822d3a71eb1f24e0d25 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:11 +0900 Subject: ARM: SAMSUNG: Add adc registers for S3C2443/S3C2416 The adc blocks of the S3C2443 and S3C2416 define some additional registers and bits. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/regs-adc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h index 035e8c38d69c..70612100120f 100644 --- a/arch/arm/plat-samsung/include/plat/regs-adc.h +++ b/arch/arm/plat-samsung/include/plat/regs-adc.h @@ -20,6 +20,7 @@ #define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C) #define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) #define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) +#define S3C2443_ADCMUX S3C2410_ADCREG(0x18) #define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) #define S5P_ADCMUX S3C2410_ADCREG(0x1C) #define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) @@ -33,6 +34,7 @@ #define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6) #define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3) #define S3C2410_ADCCON_MUXMASK (0x7<<3) +#define S3C2416_ADCCON_RESSEL (1 << 3) #define S3C2410_ADCCON_STDBM (1<<2) #define S3C2410_ADCCON_READ_START (1<<1) #define S3C2410_ADCCON_ENABLE_START (1<<0) @@ -40,6 +42,7 @@ /* ADCTSC Register Bits */ +#define S3C2443_ADCTSC_UD_SEN (1 << 8) #define S3C2410_ADCTSC_YM_SEN (1<<7) #define S3C2410_ADCTSC_YP_SEN (1<<6) #define S3C2410_ADCTSC_XM_SEN (1<<5) -- cgit v1.2.3 From df303e0236417ca006e04116f18641dbe4bd704a Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:11 +0900 Subject: ARM: SAMSUNG: Fix mux bit modification in s3c_adc_select The mux bits in the adccon register should be cleared only if muxing is really done in ADCCON and not another register. This patch introduces a conditional for this. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/adc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index ee8deef19481..7821055a5046 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -98,7 +98,8 @@ static inline void s3c_adc_select(struct adc_device *adc, client->select_cb(client, 1); - con &= ~S3C2410_ADCCON_MUXMASK; + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2) + con &= ~S3C2410_ADCCON_MUXMASK; con &= ~S3C2410_ADCCON_STDBM; con &= ~S3C2410_ADCCON_STARTMASK; -- cgit v1.2.3 From f8c414b516e17328bb1ab359b273c76a2e665b68 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:12 +0900 Subject: ARM: SAMSUNG: Allow overriding of adc device name for S3C24XX The adc blocks of S3C2443 and S3C2416 contain quirks not present in the stock S3C24xx adc. Therefore allow them to alter the device name via s3c_adc_setname. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/adc-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h index a281568d5856..a927bee55359 100644 --- a/arch/arm/plat-samsung/include/plat/adc-core.h +++ b/arch/arm/plat-samsung/include/plat/adc-core.h @@ -20,7 +20,7 @@ /* re-define device name depending on support. */ static inline void s3c_adc_setname(char *name) { -#ifdef CONFIG_SAMSUNG_DEV_ADC +#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX) s3c_device_adc.name = name; #endif } -- cgit v1.2.3 From 6247cea2b9c193a845a01381c36e18f11676fdfb Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:12 +0900 Subject: ARM: SAMSUNG: Add support s3c2443-adc for S3C2443 The S3C2443-adc is 10 bit wide and has its mux-select in an extra register at base+0x18 Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/adc.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 7821055a5046..8d8c4cc023db 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -41,6 +41,7 @@ enum s3c_cpu_type { TYPE_ADCV1, /* S3C24XX */ + TYPE_ADCV11, /* S3C2443 */ TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */ }; @@ -106,6 +107,9 @@ static inline void s3c_adc_select(struct adc_device *adc, if (!client->is_ts) { if (cpu == TYPE_ADCV3) writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); + else if (cpu == TYPE_ADCV11) + writel(client->channel & 0xf, + adc->regs + S3C2443_ADCMUX); else con |= S3C2410_ADCCON_SELMUX(client->channel); } @@ -294,13 +298,13 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) client->nr_samples--; - if (cpu != TYPE_ADCV1) { + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) { + data0 &= 0x3ff; + data1 &= 0x3ff; + } else { /* S3C64XX/S5P ADC resolution is 12-bit */ data0 &= 0xfff; data1 &= 0xfff; - } else { - data0 &= 0x3ff; - data1 &= 0x3ff; } if (client->convert_cb) @@ -321,7 +325,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) } exit: - if (cpu != TYPE_ADCV1) { + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) { /* Clear ADC interrupt */ writel(0, adc->regs + S3C64XX_ADCCLRINT); } @@ -492,6 +496,9 @@ static struct platform_device_id s3c_adc_driver_ids[] = { { .name = "s3c24xx-adc", .driver_data = TYPE_ADCV1, + }, { + .name = "s3c2443-adc", + .driver_data = TYPE_ADCV11, }, { .name = "s3c64xx-adc", .driver_data = TYPE_ADCV2, -- cgit v1.2.3 From 35cc3cea2c2adb825dbe987000165005d28acaec Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:12 +0900 Subject: ARM: SAMSUNG: Add support s3c2416-adc for S3C2416/S3C2450 The ADC of the S3C2416/2450 SoC is 10 or 12 bit wide, has its source selection in the register base+0x18 and its width selection in bit 03 of the ADCCON register. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/adc.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 8d8c4cc023db..33ecd0c9f0c3 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -42,6 +42,7 @@ enum s3c_cpu_type { TYPE_ADCV1, /* S3C24XX */ TYPE_ADCV11, /* S3C2443 */ + TYPE_ADCV12, /* S3C2416, S3C2450 */ TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */ }; @@ -107,7 +108,7 @@ static inline void s3c_adc_select(struct adc_device *adc, if (!client->is_ts) { if (cpu == TYPE_ADCV3) writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); - else if (cpu == TYPE_ADCV11) + else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12) writel(client->channel & 0xf, adc->regs + S3C2443_ADCMUX); else @@ -302,7 +303,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) data0 &= 0x3ff; data1 &= 0x3ff; } else { - /* S3C64XX/S5P ADC resolution is 12-bit */ + /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */ data0 &= 0xfff; data1 &= 0xfff; } @@ -337,6 +338,7 @@ static int s3c_adc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct adc_device *adc; struct resource *regs; + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; int ret; unsigned tmp; @@ -399,10 +401,13 @@ static int s3c_adc_probe(struct platform_device *pdev) clk_enable(adc->clk); tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; - if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) { - /* Enable 12-bit ADC resolution */ + + /* Enable 12-bit ADC resolution */ + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) tmp |= S3C64XX_ADCCON_RESSEL; - } + writel(tmp, adc->regs + S3C2410_ADCCON); dev_info(dev, "attached adc driver\n"); @@ -469,6 +474,7 @@ static int s3c_adc_resume(struct device *dev) struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct adc_device *adc = platform_get_drvdata(pdev); + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; int ret; unsigned long tmp; @@ -479,9 +485,13 @@ static int s3c_adc_resume(struct device *dev) enable_irq(adc->irq); tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; + /* Enable 12-bit ADC resolution */ - if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) tmp |= S3C64XX_ADCCON_RESSEL; + writel(tmp, adc->regs + S3C2410_ADCCON); return 0; @@ -499,6 +509,9 @@ static struct platform_device_id s3c_adc_driver_ids[] = { }, { .name = "s3c2443-adc", .driver_data = TYPE_ADCV11, + }, { + .name = "s3c2416-adc", + .driver_data = TYPE_ADCV12, }, { .name = "s3c64xx-adc", .driver_data = TYPE_ADCV2, -- cgit v1.2.3 From d9a3bfbd7e80ecf24d2322659d5c0542f9d95e78 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 14 Oct 2011 15:08:56 +0900 Subject: ARM: S3C24XX: Add infrastructure to transmit armdiv to common code This is needed for making the armdiv clock common to S3C2443 and S3C2416/2450. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/s3c2443.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h index 4b2ac9a272b2..5fc4ad0fd756 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ b/arch/arm/plat-samsung/include/plat/s3c2443.h @@ -40,7 +40,9 @@ typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); typedef unsigned int (*fdiv_fn)(unsigned long clkcon0); extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); -extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv, + unsigned int *divs, int nr_divs, + int divmask); extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); -- cgit v1.2.3 From 33ccedfd1b79a7cf649b2991e95bae415c013240 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 14 Oct 2011 15:08:57 +0900 Subject: ARM: S3C24XX: use clk_get_rate to init fclk in common_setup_clocks Previously the fclk rate was calculated by dividing the pll through the divider value of the armdiv. With a real armdiv clk in place it's possible to simply read its value, which does essentially the same. This change makes the whole fdiv_fn function pointers supplied to s3c2443_common_init_clocks and s3c2443_common_setup_clocks obsolete, so remove it too. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/s3c2443.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h index 5fc4ad0fd756..7fae1a050694 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ b/arch/arm/plat-samsung/include/plat/s3c2443.h @@ -37,10 +37,9 @@ extern int s3c2443_baseclk_add(void); struct clk; /* some files don't need clk.h otherwise */ typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); -typedef unsigned int (*fdiv_fn)(unsigned long clkcon0); -extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); -extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv, +extern void s3c2443_common_setup_clocks(pll_fn get_mpll); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, unsigned int *divs, int nr_divs, int divmask); -- cgit v1.2.3 From 0f4e54c64eacab06675a054a861d6e0b7442ec9e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 18 Oct 2011 08:39:57 +0900 Subject: ARM: S3C64XX: Fix SoC identification for S3C64xx devices The IS_SAMSUNG_CPU() macro works by comparing the CPU ID mask exactly with the CPU ID. This was failing for S3C64xx SoCs as in order to support identification of the exact device the mask covers both variants of the chip, meaning that the test would always fail on S3C6410 devices. This in turn caused the core GPIO subsystem to fail to identify the CPU and not support any GPIOs, crippling the system. As a minimally invasive fix change the test for the class to be done by checking each implementation and oring them together. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/cpu.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 54f370f0fc07..40fd7b6b5e66 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -25,7 +25,6 @@ extern unsigned long samsung_cpu_id; #define S3C6400_CPU_ID 0x36400000 #define S3C6410_CPU_ID 0x36410000 -#define S3C64XX_CPU_ID (S3C6400_CPU_ID & S3C6410_CPU_ID) #define S3C64XX_CPU_MASK 0xFFFFF000 #define S5P6440_CPU_ID 0x56440000 @@ -50,7 +49,8 @@ static inline int is_samsung_##name(void) \ } IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) -IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK) IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK) IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK) IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK) @@ -69,7 +69,7 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK) #endif #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) -# define soc_is_s3c64xx() is_samsung_s3c64xx() +# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) #else # define soc_is_s3c64xx() 0 #endif -- cgit v1.2.3