diff options
-rw-r--r-- | arch/arm/mach-mx28/device.c | 38 | ||||
-rw-r--r-- | arch/arm/plat-mxs/device.c | 18 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/device.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-mxs/lradc.c | 243 |
4 files changed, 209 insertions, 95 deletions
diff --git a/arch/arm/mach-mx28/device.c b/arch/arm/mach-mx28/device.c index a37f0c7538fa..b393af4110fb 100644 --- a/arch/arm/mach-mx28/device.c +++ b/arch/arm/mach-mx28/device.c @@ -32,8 +32,10 @@ #include <mach/hardware.h> #include <mach/regs-timrot.h> +#include <mach/regs-lradc.h> #include <mach/device.h> #include <mach/dma.h> +#include <mach/lradc.h> #include "device.h" #include "mx28_pins.h" @@ -548,6 +550,7 @@ static struct resource fec_resources[] = { .flags = IORESOURCE_IRQ }, }; + extern int mx28evk_enet_gpio_init(void); static struct fec_platform_data fec_pdata = { .phy = PHY_INTERFACE_MODE_RMII, @@ -557,9 +560,11 @@ static struct fec_platform_data fec_pdata = { static void __init mx28_init_fec(void) { struct platform_device *pdev; + pdev = mxs_get_device("mxs-fec", 0); if (pdev == NULL || IS_ERR(pdev)) return; + pdev->resource = fec_resources; pdev->num_resources = ARRAY_SIZE(fec_resources); pdev->dev.platform_data = &fec_pdata; @@ -571,12 +576,45 @@ static void __init mx28_init_fec(void) ; } #endif +#ifdef CONFIG_MXS_LRADC +struct mxs_lradc_plat_data mx28_lradc_data = { + .vddio_voltage = BV_LRADC_CTRL4_LRADC6SELECT__CHANNEL10, + .battery_voltage = BV_LRADC_CTRL4_LRADC7SELECT__CHANNEL7, +}; + +static struct resource mx28_lradc_res[] = { + { + .flags = IORESOURCE_MEM, + .start = LRADC_PHYS_ADDR, + .end = LRADC_PHYS_ADDR + 0x2000 - 1, + }, +}; + +static void __init mx28_init_lradc(void) +{ + struct platform_device *pdev; + + pdev = mxs_get_device("mxs-lradc", 0); + if (pdev == NULL || IS_ERR(pdev)) + return; + pdev->resource = mx28_lradc_res; + pdev->num_resources = ARRAY_SIZE(mx28_lradc_res); + pdev->dev.platform_data = &mx28_lradc_data; + mxs_add_device(pdev, 0); +} +#else +static void __init mx28_init_lradc(void) +{ + ; +} +#endif int __init mx28_device_init(void) { mx28_init_dma(); mx28_init_duart(); mx28_init_i2c(); + mx28_init_lradc(); mx28_init_mmc(); mx28_init_wdt(); mx28_init_rtc(); diff --git a/arch/arm/plat-mxs/device.c b/arch/arm/plat-mxs/device.c index 7eb37b0f0471..f3fcad718c39 100644 --- a/arch/arm/plat-mxs/device.c +++ b/arch/arm/plat-mxs/device.c @@ -206,6 +206,16 @@ static struct platform_device mxs_rtc = { }; #endif +#ifdef CONFIG_MXS_LRADC +static struct platform_device mxs_lradc = { + .name = "mxs-lradc", + .id = 0, + .dev = { + .release = mxs_nop_release, + }, +}; +#endif + static struct mxs_dev_lookup dev_lookup[] = { #if defined(CONFIG_SERIAL_MXS_DUART) || \ defined(CONFIG_SERIAL_MXS_DUART_MODULE) @@ -273,6 +283,14 @@ static struct mxs_dev_lookup dev_lookup[] = { .pdev = mxs_fec, }, #endif + +#ifdef CONFIG_MXS_LRADC + { + .name = "mxs-lradc", + .size = 1, + .pdev = &mxs_lradc, + }, +#endif }; struct platform_device *mxs_get_device(char *name, int id) diff --git a/arch/arm/plat-mxs/include/mach/device.h b/arch/arm/plat-mxs/include/mach/device.h index b362d2eea526..7083baa89245 100644 --- a/arch/arm/plat-mxs/include/mach/device.h +++ b/arch/arm/plat-mxs/include/mach/device.h @@ -57,6 +57,11 @@ struct mxs_i2c_plat_data { unsigned int pioqueue_mode:1; }; +struct mxs_lradc_plat_data { + unsigned int vddio_voltage; + unsigned int battery_voltage; +}; + extern void mxs_timer_init(struct mxs_sys_timer *timer); extern void mxs_nop_release(struct device *dev); diff --git a/arch/arm/plat-mxs/lradc.c b/arch/arm/plat-mxs/lradc.c index b7097991fdf0..3d9089e3ef25 100644 --- a/arch/arm/plat-mxs/lradc.c +++ b/arch/arm/plat-mxs/lradc.c @@ -17,19 +17,31 @@ */ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/errno.h> #include <linux/sysdev.h> +#include <linux/platform_device.h> #include <linux/bitops.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/ioport.h> #include <linux/irq.h> -#include <mach/hardware.h> #include <linux/delay.h> -#include <mach/platform.h> -#include <mach/stmp3xxx.h> + +#include <mach/hardware.h> +#include <mach/device.h> #include <mach/regs-lradc.h> #include <mach/lradc.h> +struct lradc_device { + struct sys_device sys; + unsigned int base; + unsigned int vddio_voltage; + unsigned int battery_voltage; +}; + static int channels[8]; +static __refdata struct lradc_device mxs_lradc; + int hw_lradc_use_channel(int channel) { if (channel < 0 || channel > 7) @@ -50,34 +62,34 @@ EXPORT_SYMBOL(hw_lradc_unuse_channel); void hw_lradc_reinit(int enable_ground_ref, unsigned freq) { - stmp3xxx_setl(BM_LRADC_CTRL0_SFTRST, REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_SFTRST, + mxs_lradc.base + HW_LRADC_CTRL0_SET); udelay(1); - stmp3xxx_clearl(BM_LRADC_CTRL0_SFTRST, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_SFTRST, + mxs_lradc.base + HW_LRADC_CTRL0_CLR); /* Clear the Clock Gate for normal operation */ - stmp3xxx_clearl(BM_LRADC_CTRL0_CLKGATE, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_CLKGATE, + mxs_lradc.base + HW_LRADC_CTRL0_CLR); if (enable_ground_ref) - stmp3xxx_setl(BM_LRADC_CTRL0_ONCHIP_GROUNDREF, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_ONCHIP_GROUNDREF, + mxs_lradc.base + HW_LRADC_CTRL0_SET); else - stmp3xxx_clearl(BM_LRADC_CTRL0_ONCHIP_GROUNDREF, - REGS_LRADC_BASE + HW_LRADC_CTRL0); - - stmp3xxx_clearl(BM_LRADC_CTRL3_CYCLE_TIME, - REGS_LRADC_BASE + HW_LRADC_CTRL3); - stmp3xxx_setl(BF(freq, LRADC_CTRL3_CYCLE_TIME), - REGS_LRADC_BASE + HW_LRADC_CTRL3); - - stmp3xxx_clearl(BM_LRADC_CTRL4_LRADC6SELECT | - BM_LRADC_CTRL4_LRADC7SELECT, - REGS_LRADC_BASE + HW_LRADC_CTRL4); - stmp3xxx_setl(BF(VDDIO_VOLTAGE_CH, LRADC_CTRL4_LRADC6SELECT), - REGS_LRADC_BASE + HW_LRADC_CTRL4); - stmp3xxx_setl(BF(BATTERY_VOLTAGE_CH, LRADC_CTRL4_LRADC7SELECT), - REGS_LRADC_BASE + HW_LRADC_CTRL4); + __raw_writel(BM_LRADC_CTRL0_ONCHIP_GROUNDREF, + mxs_lradc.base + HW_LRADC_CTRL0_CLR); + + __raw_writel(BM_LRADC_CTRL3_CYCLE_TIME, + mxs_lradc.base + HW_LRADC_CTRL3_CLR); + __raw_writel(BF_LRADC_CTRL3_CYCLE_TIME(freq), + mxs_lradc.base + HW_LRADC_CTRL3_SET); + + __raw_writel(BM_LRADC_CTRL4_LRADC6SELECT | BM_LRADC_CTRL4_LRADC7SELECT, + mxs_lradc.base + HW_LRADC_CTRL4_CLR); + __raw_writel(BF_LRADC_CTRL4_LRADC6SELECT(mxs_lradc.vddio_voltage), + mxs_lradc.base + HW_LRADC_CTRL4_SET); + __raw_writel(BF_LRADC_CTRL4_LRADC7SELECT(mxs_lradc.battery_voltage), + mxs_lradc.base + HW_LRADC_CTRL4_SET); } int hw_lradc_init_ladder(int channel, int trigger, unsigned sampling) @@ -97,7 +109,7 @@ int hw_lradc_init_ladder(int channel, int trigger, unsigned sampling) 1 << trigger, 0, sampling); /* Clear the accumulator & NUM_SAMPLES */ - stmp3xxx_clearl(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn(channel)); + __raw_writel(0xFFFFFFFF, mxs_lradc.base + HW_LRADC_CHn_CLR(channel)); return 0; } @@ -120,7 +132,7 @@ int hw_lradc_present(int channel) { if (channel < 0 || channel > 7) return 0; - return __raw_readl(REGS_LRADC_BASE + HW_LRADC_STATUS) + return __raw_readl(mxs_lradc.base + HW_LRADC_STATUS) & (1 << (16 + channel)); } @@ -130,27 +142,27 @@ void hw_lradc_configure_channel(int channel, int enable_div2, int enable_acc, int samples) { if (enable_div2) - stmp3xxx_setl(BF(1 << channel, LRADC_CTRL2_DIVIDE_BY_TWO), - REGS_LRADC_BASE + HW_LRADC_CTRL2); + __raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << channel), + mxs_lradc.base + HW_LRADC_CTRL2_SET); else - stmp3xxx_clearl(BF(1 << channel, LRADC_CTRL2_DIVIDE_BY_TWO), - REGS_LRADC_BASE + HW_LRADC_CTRL2); + __raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << channel), + mxs_lradc.base + HW_LRADC_CTRL2_CLR); /* Clear the accumulator & NUM_SAMPLES */ - stmp3xxx_clearl(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn(channel)); + __raw_writel(0xFFFFFFFF, mxs_lradc.base + HW_LRADC_CHn_CLR(channel)); /* Sets NUM_SAMPLES bitfield of HW_LRADC_CHn register. */ - stmp3xxx_clearl(BM_LRADC_CHn_NUM_SAMPLES, - REGS_LRADC_BASE + HW_LRADC_CHn(channel)); - stmp3xxx_setl(BF(samples, LRADC_CHn_NUM_SAMPLES), - REGS_LRADC_BASE + HW_LRADC_CHn(channel)); + __raw_writel(BM_LRADC_CHn_NUM_SAMPLES, + mxs_lradc.base + HW_LRADC_CHn_CLR(channel)); + __raw_writel(BF_LRADC_CHn_NUM_SAMPLES(samples), + mxs_lradc.base + HW_LRADC_CHn_SET(channel)); if (enable_acc) - stmp3xxx_setl(BM_LRADC_CHn_ACCUMULATE, - REGS_LRADC_BASE + HW_LRADC_CHn(channel)); + __raw_writel(BM_LRADC_CHn_ACCUMULATE, + mxs_lradc.base + HW_LRADC_CHn_SET(channel)); else - stmp3xxx_clearl(BM_LRADC_CHn_ACCUMULATE, - REGS_LRADC_BASE + HW_LRADC_CHn(channel)); + __raw_writel(BM_LRADC_CHn_ACCUMULATE, + mxs_lradc.base + HW_LRADC_CHn_CLR(channel)); } EXPORT_SYMBOL(hw_lradc_configure_channel); @@ -159,17 +171,17 @@ void hw_lradc_set_delay_trigger(int trigger, u32 trigger_lradc, u32 delay_triggers, u32 loops, u32 delays) { /* set TRIGGER_LRADCS in HW_LRADC_DELAYn */ - stmp3xxx_setl(BF(trigger_lradc, LRADC_DELAYn_TRIGGER_LRADCS), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); - stmp3xxx_setl(BF(delay_triggers, LRADC_DELAYn_TRIGGER_DELAYS), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); - - stmp3xxx_clearl(BM_LRADC_DELAYn_LOOP_COUNT | BM_LRADC_DELAYn_DELAY, - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); - stmp3xxx_setl(BF(loops, LRADC_DELAYn_LOOP_COUNT), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); - stmp3xxx_setl(BF(delays, LRADC_DELAYn_DELAY), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); + __raw_writel(BF_LRADC_DELAYn_TRIGGER_LRADCS(trigger_lradc), + mxs_lradc.base + HW_LRADC_DELAYn_SET(trigger)); + __raw_writel(BF_LRADC_DELAYn_TRIGGER_DELAYS(delay_triggers), + mxs_lradc.base + HW_LRADC_DELAYn_SET(trigger)); + + __raw_writel(BM_LRADC_DELAYn_LOOP_COUNT | BM_LRADC_DELAYn_DELAY, + mxs_lradc.base + HW_LRADC_DELAYn_CLR(trigger)); + __raw_writel(BF_LRADC_DELAYn_LOOP_COUNT(loops), + mxs_lradc.base + HW_LRADC_DELAYn_SET(trigger)); + __raw_writel(BF_LRADC_DELAYn_DELAY(delays), + mxs_lradc.base + HW_LRADC_DELAYn_SET(trigger)); } EXPORT_SYMBOL(hw_lradc_set_delay_trigger); @@ -177,10 +189,10 @@ EXPORT_SYMBOL(hw_lradc_set_delay_trigger); void hw_lradc_clear_delay_trigger(int trigger, u32 trigger_lradc, u32 delay_triggers) { - stmp3xxx_clearl(BF(trigger_lradc, LRADC_DELAYn_TRIGGER_LRADCS), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); - stmp3xxx_clearl(BF(delay_triggers, LRADC_DELAYn_TRIGGER_DELAYS), - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); + __raw_writel(BF_LRADC_DELAYn_TRIGGER_LRADCS(trigger_lradc), + mxs_lradc.base + HW_LRADC_DELAYn_CLR(trigger)); + __raw_writel(BF_LRADC_DELAYn_TRIGGER_DELAYS(delay_triggers), + mxs_lradc.base + HW_LRADC_DELAYn_CLR(trigger)); } EXPORT_SYMBOL(hw_lradc_clear_delay_trigger); @@ -188,11 +200,11 @@ EXPORT_SYMBOL(hw_lradc_clear_delay_trigger); void hw_lradc_set_delay_trigger_kick(int trigger, int value) { if (value) - stmp3xxx_setl(BM_LRADC_DELAYn_KICK, - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); + __raw_writel(BM_LRADC_DELAYn_KICK, + mxs_lradc.base + HW_LRADC_DELAYn_SET(trigger)); else - stmp3xxx_clearl(BM_LRADC_DELAYn_KICK, - REGS_LRADC_BASE + HW_LRADC_DELAYn(trigger)); + __raw_writel(BM_LRADC_DELAYn_KICK, + mxs_lradc.base + HW_LRADC_DELAYn_CLR(trigger)); } EXPORT_SYMBOL(hw_lradc_set_delay_trigger_kick); @@ -200,48 +212,49 @@ EXPORT_SYMBOL(hw_lradc_set_delay_trigger_kick); u32 hw_lradc_vddio(void) { /* Clear the Soft Reset and Clock Gate for normal operation */ - stmp3xxx_clearl(BM_LRADC_CTRL0_SFTRST | BM_LRADC_CTRL0_CLKGATE, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_SFTRST | BM_LRADC_CTRL0_CLKGATE, + mxs_lradc.base + HW_LRADC_CTRL0_CLR); /* * Clear the divide by two for channel 6 since * it has a HW divide-by-two built in. */ - stmp3xxx_clearl(BF(1 << VDDIO_VOLTAGE_CH, LRADC_CTRL2_DIVIDE_BY_TWO), - REGS_LRADC_BASE + HW_LRADC_CTRL2); + __raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << VDDIO_VOLTAGE_CH), + mxs_lradc.base + HW_LRADC_CTRL2_CLR); /* Clear the accumulator & NUM_SAMPLES */ - stmp3xxx_clearl(0xFFFFFFFF, - REGS_LRADC_BASE + HW_LRADC_CHn(VDDIO_VOLTAGE_CH)); + __raw_writel(0xFFFFFFFF, + mxs_lradc.base + HW_LRADC_CHn_CLR(VDDIO_VOLTAGE_CH)); /* Clear the interrupt flag */ - stmp3xxx_clearl(BM_LRADC_CTRL1_LRADC6_IRQ, - REGS_LRADC_BASE + HW_LRADC_CTRL1); + __raw_writel(BM_LRADC_CTRL1_LRADC6_IRQ, + mxs_lradc.base + HW_LRADC_CTRL1_CLR); /* * Get VddIO; this is the max scale value for the button resistor * ladder. * schedule ch 6: */ - stmp3xxx_setl(BF(1 << VDDIO_VOLTAGE_CH, LRADC_CTRL0_SCHEDULE), - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BF_LRADC_CTRL0_SCHEDULE(1 << VDDIO_VOLTAGE_CH), + mxs_lradc.base + HW_LRADC_CTRL0_SET); /* wait for completion */ - while ((__raw_readl(REGS_LRADC_BASE + HW_LRADC_CTRL1) + while ((__raw_readl(mxs_lradc.base + HW_LRADC_CTRL1) & BM_LRADC_CTRL1_LRADC6_IRQ) != BM_LRADC_CTRL1_LRADC6_IRQ) cpu_relax(); /* Clear the interrupt flag */ - stmp3xxx_clearl(BM_LRADC_CTRL1_LRADC6_IRQ, - REGS_LRADC_BASE + HW_LRADC_CTRL1); + __raw_writel(BM_LRADC_CTRL1_LRADC6_IRQ, + mxs_lradc.base + HW_LRADC_CTRL1_CLR); /* read ch 6 value. */ - return __raw_readl(REGS_LRADC_BASE + HW_LRADC_CHn(6)) - & BM_LRADC_CHn_VALUE; + return __raw_readl(mxs_lradc.base + HW_LRADC_CHn(VDDIO_VOLTAGE_CH)) & + BM_LRADC_CHn_VALUE; } EXPORT_SYMBOL(hw_lradc_vddio); +#ifdef CONFIG_PM static u32 lradc_registers[0x16]; static int do_gate; @@ -257,11 +270,11 @@ static int hw_lradc_suspend(struct sys_device *dev, pm_message_t state) } for (i = 0; i < ARRAY_SIZE(lradc_registers); i++) - lradc_registers[i] = __raw_readl(REGS_LRADC_BASE + (i << 4)); + lradc_registers[i] = __raw_readl(mxs_lradc.base + (i << 4)); if (do_gate) - stmp3xxx_setl(BM_LRADC_CTRL0_CLKGATE, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_CLKGATE, + mxs_lradc.base + HW_LRADC_CTRL0_SET); return 0; } @@ -270,32 +283,29 @@ static int hw_lradc_resume(struct sys_device *dev) int i; if (do_gate) { - stmp3xxx_setl(BM_LRADC_CTRL0_SFTRST, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_SFTRST, + mxs_lradc.base + HW_LRADC_CTRL0_SET); udelay(10); - stmp3xxx_clearl(BM_LRADC_CTRL0_SFTRST | - BM_LRADC_CTRL0_CLKGATE, - REGS_LRADC_BASE + HW_LRADC_CTRL0); + __raw_writel(BM_LRADC_CTRL0_SFTRST | + BM_LRADC_CTRL0_CLKGATE, + mxs_lradc.base + HW_LRADC_CTRL0_CLR); } for (i = 0; i < ARRAY_SIZE(lradc_registers); i++) - __raw_writel(lradc_registers[i], REGS_LRADC_BASE + (i << 4)); + __raw_writel(lradc_registers[i], mxs_lradc.base + (i << 4)); return 0; } -static struct sysdev_class stmp3xxx_lradc_sysclass = { - .name = "stmp3xxx-lradc", +#endif + +static struct sysdev_class mxs_lradc_sysclass = { + .name = "mxs-lradc", #ifdef CONFIG_PM .suspend = hw_lradc_suspend, .resume = hw_lradc_resume, #endif }; -static struct sys_device stmp3xxx_lradc_device = { - .id = -1, - .cls = &stmp3xxx_lradc_sysclass, -}; - -static int __initdata lradc_freq = LRADC_CLOCK_6MHZ; +static int lradc_freq = LRADC_CLOCK_6MHZ; static int __init lradc_freq_setup(char *str) { @@ -321,12 +331,55 @@ static int __init lradc_freq_setup(char *str) __setup("lradc_freq=", lradc_freq_setup); -static int __init hw_lradc_init(void) +static int __devinit mxs_lradc_probe(struct platform_device *pdev) { + struct resource *res; + struct mxs_lradc_plat_data *plat_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENODEV; + + plat_data = (struct mxs_lradc_plat_data *)(pdev->dev.platform_data); + if (plat_data == NULL) + return -EFAULT; + + mxs_lradc.base = (unsigned int)IO_ADDRESS(res->start); + mxs_lradc.sys.id = -1; + mxs_lradc.sys.cls = &mxs_lradc_sysclass; + mxs_lradc.vddio_voltage = plat_data->vddio_voltage; + mxs_lradc.battery_voltage = plat_data->battery_voltage; hw_lradc_reinit(0, lradc_freq); - sysdev_class_register(&stmp3xxx_lradc_sysclass); - sysdev_register(&stmp3xxx_lradc_device); + return sysdev_register(&mxs_lradc.sys); +} + +static int __devexit mxs_lradc_remove(struct platform_device *pdev) +{ + sysdev_unregister(&mxs_lradc.sys); return 0; } +static __refdata struct platform_driver mxs_lradc_drv = { + .probe = mxs_lradc_probe, + .remove = __devexit_p(mxs_lradc_remove), + .driver = { + .name = "mxs-lradc", + .owner = THIS_MODULE, + } +}; + +static int __init hw_lradc_init(void) +{ + sysdev_class_register(&mxs_lradc_sysclass); + platform_driver_register(&mxs_lradc_drv); + return 0; +} + +static void __exit hw_lradc_exit(void) +{ + platform_driver_unregister(&mxs_lradc_drv); + sysdev_class_unregister(&mxs_lradc_sysclass); +} + subsys_initcall(hw_lradc_init); +module_exit(hw_lradc_exit); |