Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2010 DENX Software Engineering
0004  *
0005  * Anatolij Gustschin, <agust@denx.de>
0006  *
0007  * PDM360NG board setup
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     /* return 1 if pen is down */
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 /* CONFIG_TOUCHSCREEN_ADS7846 */
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 };