0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/io.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_fdt.h>
0014 #include <linux/of_platform.h>
0015
0016 #include <asm/machdep.h>
0017 #include <asm/ipic.h>
0018
0019 #include "mpc512x.h"
0020
0021 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
0022 defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
0023 #include <linux/interrupt.h>
0024 #include <linux/spi/ads7846.h>
0025 #include <linux/spi/spi.h>
0026 #include <linux/notifier.h>
0027
0028 static void *pdm360ng_gpio_base;
0029
0030 static int pdm360ng_get_pendown_state(void)
0031 {
0032 u32 reg;
0033
0034 reg = in_be32(pdm360ng_gpio_base + 0xc);
0035 if (reg & 0x40)
0036 setbits32(pdm360ng_gpio_base + 0xc, 0x40);
0037
0038 reg = in_be32(pdm360ng_gpio_base + 0x8);
0039
0040
0041 return (reg & 0x40) == 0;
0042 }
0043
0044 static struct ads7846_platform_data pdm360ng_ads7846_pdata = {
0045 .model = 7845,
0046 .get_pendown_state = pdm360ng_get_pendown_state,
0047 .irq_flags = IRQF_TRIGGER_LOW,
0048 };
0049
0050 static int __init pdm360ng_penirq_init(void)
0051 {
0052 struct device_node *np;
0053
0054 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio");
0055 if (!np) {
0056 pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__);
0057 return -ENODEV;
0058 }
0059
0060 pdm360ng_gpio_base = of_iomap(np, 0);
0061 of_node_put(np);
0062 if (!pdm360ng_gpio_base) {
0063 pr_err("%s: Can't map gpio regs.\n", __func__);
0064 return -ENODEV;
0065 }
0066 out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff);
0067 setbits32(pdm360ng_gpio_base + 0x18, 0x2000);
0068 setbits32(pdm360ng_gpio_base + 0x10, 0x40);
0069
0070 return 0;
0071 }
0072
0073 static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb,
0074 unsigned long event, void *__dev)
0075 {
0076 struct device *dev = __dev;
0077
0078 if ((event == BUS_NOTIFY_ADD_DEVICE) &&
0079 of_device_is_compatible(dev->of_node, "ti,ads7846")) {
0080 dev->platform_data = &pdm360ng_ads7846_pdata;
0081 return NOTIFY_OK;
0082 }
0083 return NOTIFY_DONE;
0084 }
0085
0086 static struct notifier_block pdm360ng_touchscreen_nb = {
0087 .notifier_call = pdm360ng_touchscreen_notifier_call,
0088 };
0089
0090 static void __init pdm360ng_touchscreen_init(void)
0091 {
0092 if (pdm360ng_penirq_init())
0093 return;
0094
0095 bus_register_notifier(&spi_bus_type, &pdm360ng_touchscreen_nb);
0096 }
0097 #else
0098 static inline void __init pdm360ng_touchscreen_init(void)
0099 {
0100 }
0101 #endif
0102
0103 void __init pdm360ng_init(void)
0104 {
0105 mpc512x_init();
0106 pdm360ng_touchscreen_init();
0107 }
0108
0109 static int __init pdm360ng_probe(void)
0110 {
0111 if (!of_machine_is_compatible("ifm,pdm360ng"))
0112 return 0;
0113
0114 mpc512x_init_early();
0115
0116 return 1;
0117 }
0118
0119 define_machine(pdm360ng) {
0120 .name = "PDM360NG",
0121 .probe = pdm360ng_probe,
0122 .setup_arch = mpc512x_setup_arch,
0123 .init = pdm360ng_init,
0124 .init_IRQ = mpc512x_init_IRQ,
0125 .get_irq = ipic_get_irq,
0126 .calibrate_decr = generic_calibrate_decr,
0127 .restart = mpc512x_restart,
0128 };