• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/powerpc/platforms/512x/
1/*
2 * Copyright (C) 2010 DENX Software Engineering
3 *
4 * Anatolij Gustschin, <agust@denx.de>
5 *
6 * PDM360NG board setup
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/io.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/ipic.h>
21
22#include "mpc512x.h"
23
24#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
25#include <linux/interrupt.h>
26#include <linux/spi/ads7846.h>
27#include <linux/spi/spi.h>
28#include <linux/notifier.h>
29
30static void *pdm360ng_gpio_base;
31
32static int pdm360ng_get_pendown_state(void)
33{
34	u32 reg;
35
36	reg = in_be32(pdm360ng_gpio_base + 0xc);
37	if (reg & 0x40)
38		setbits32(pdm360ng_gpio_base + 0xc, 0x40);
39
40	reg = in_be32(pdm360ng_gpio_base + 0x8);
41
42	/* return 1 if pen is down */
43	return (reg & 0x40) == 0;
44}
45
46static struct ads7846_platform_data pdm360ng_ads7846_pdata = {
47	.model			= 7845,
48	.get_pendown_state	= pdm360ng_get_pendown_state,
49	.irq_flags		= IRQF_TRIGGER_LOW,
50};
51
52static int __init pdm360ng_penirq_init(void)
53{
54	struct device_node *np;
55
56	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio");
57	if (!np) {
58		pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__);
59		return -ENODEV;
60	}
61
62	pdm360ng_gpio_base = of_iomap(np, 0);
63	of_node_put(np);
64	if (!pdm360ng_gpio_base) {
65		pr_err("%s: Can't map gpio regs.\n", __func__);
66		return -ENODEV;
67	}
68	out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff);
69	setbits32(pdm360ng_gpio_base + 0x18, 0x2000);
70	setbits32(pdm360ng_gpio_base + 0x10, 0x40);
71
72	return 0;
73}
74
75static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb,
76					unsigned long event, void *__dev)
77{
78	struct device *dev = __dev;
79
80	if ((event == BUS_NOTIFY_ADD_DEVICE) &&
81	    of_device_is_compatible(dev->of_node, "ti,ads7846")) {
82		dev->platform_data = &pdm360ng_ads7846_pdata;
83		return NOTIFY_OK;
84	}
85	return NOTIFY_DONE;
86}
87
88static struct notifier_block pdm360ng_touchscreen_nb = {
89	.notifier_call = pdm360ng_touchscreen_notifier_call,
90};
91
92static void __init pdm360ng_touchscreen_init(void)
93{
94	if (pdm360ng_penirq_init())
95		return;
96
97	bus_register_notifier(&spi_bus_type, &pdm360ng_touchscreen_nb);
98}
99#else
100static inline void __init pdm360ng_touchscreen_init(void)
101{
102}
103#endif /* CONFIG_TOUCHSCREEN_ADS7846 */
104
105void __init pdm360ng_init(void)
106{
107	mpc512x_init();
108	pdm360ng_touchscreen_init();
109}
110
111static int __init pdm360ng_probe(void)
112{
113	unsigned long root = of_get_flat_dt_root();
114
115	return of_flat_dt_is_compatible(root, "ifm,pdm360ng");
116}
117
118define_machine(pdm360ng) {
119	.name			= "PDM360NG",
120	.probe			= pdm360ng_probe,
121	.setup_arch		= mpc512x_setup_diu,
122	.init			= pdm360ng_init,
123	.init_early		= mpc512x_init_diu,
124	.init_IRQ		= mpc512x_init_IRQ,
125	.get_irq		= ipic_get_irq,
126	.calibrate_decr		= generic_calibrate_decr,
127	.restart		= mpc512x_restart,
128};
129