source: src/linux/universal/linux-3.2/arch/mips/lantiq/xway/gpio_stp.c @ 18171

Last change on this file since 18171 was 18171, checked in by BrainSlayer, 16 months ago

this kernel will be maintained for all targets, so target specific kernel trees will not be neccessary anymore in future

File size: 3.8 KB
Line 
1/*
2 *  This program is free software; you can redistribute it and/or modify it
3 *  under the terms of the GNU General Public License version 2 as published
4 *  by the Free Software Foundation.
5 *
6 *  Copyright (C) 2007 John Crispin <blogic@openwrt.org>
7 *
8 */
9
10#include <linux/slab.h>
11#include <linux/init.h>
12#include <linux/export.h>
13#include <linux/types.h>
14#include <linux/platform_device.h>
15#include <linux/mutex.h>
16#include <linux/io.h>
17#include <linux/gpio.h>
18
19#include <lantiq_soc.h>
20
21#define LTQ_STP_CON0            0x00
22#define LTQ_STP_CON1            0x04
23#define LTQ_STP_CPU0            0x08
24#define LTQ_STP_CPU1            0x0C
25#define LTQ_STP_AR              0x10
26
27#define LTQ_STP_CON_SWU         (1 << 31)
28#define LTQ_STP_2HZ             0
29#define LTQ_STP_4HZ             (1 << 23)
30#define LTQ_STP_8HZ             (2 << 23)
31#define LTQ_STP_10HZ            (3 << 23)
32#define LTQ_STP_SPEED_MASK      (0xf << 23)
33#define LTQ_STP_UPD_FPI         (1 << 31)
34#define LTQ_STP_UPD_MASK        (3 << 30)
35#define LTQ_STP_ADSL_SRC        (3 << 24)
36
37#define LTQ_STP_GROUP0          (1 << 0)
38
39#define LTQ_STP_RISING          0
40#define LTQ_STP_FALLING         (1 << 26)
41#define LTQ_STP_EDGE_MASK       (1 << 26)
42
43#define ltq_stp_r32(reg)        __raw_readl(ltq_stp_membase + reg)
44#define ltq_stp_w32(val, reg)   __raw_writel(val, ltq_stp_membase + reg)
45#define ltq_stp_w32_mask(clear, set, reg) \
46                ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
47                ltq_stp_membase + (reg))
48
49static int ltq_stp_shadow = 0xffff;
50static void __iomem *ltq_stp_membase;
51
52static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
53{
54        if (value)
55                ltq_stp_shadow |= (1 << offset);
56        else
57                ltq_stp_shadow &= ~(1 << offset);
58        ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
59}
60
61static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
62        int value)
63{
64        ltq_stp_set(chip, offset, value);
65
66        return 0;
67}
68
69static struct gpio_chip ltq_stp_chip = {
70        .label = "ltq_stp",
71        .direction_output = ltq_stp_direction_output,
72        .set = ltq_stp_set,
73        .base = 48,
74        .ngpio = 24,
75        .can_sleep = 1,
76        .owner = THIS_MODULE,
77};
78
79static int ltq_stp_hw_init(void)
80{
81        /* the 3 pins used to control the external stp */
82        ltq_gpio_request(4, 1, 0, 1, "stp-st");
83        ltq_gpio_request(5, 1, 0, 1, "stp-d");
84        ltq_gpio_request(6, 1, 0, 1, "stp-sh");
85
86        /* sane defaults */
87        ltq_stp_w32(0, LTQ_STP_AR);
88        ltq_stp_w32(0, LTQ_STP_CPU0);
89        ltq_stp_w32(0, LTQ_STP_CPU1);
90        ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
91        ltq_stp_w32(0, LTQ_STP_CON1);
92
93        /* rising or falling edge */
94        ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
95
96        /* per default stp 15-0 are set */
97        ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
98
99        /* stp are update periodically by the FPI bus */
100        ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
101
102        /* set stp update speed */
103        ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
104
105        /* tell the hardware that pin (led) 0 and 1 are controlled
106         *  by the dsl arc
107         */
108        ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
109
110        ltq_pmu_enable(PMU_LED);
111        return 0;
112}
113
114static int __devinit ltq_stp_probe(struct platform_device *pdev)
115{
116        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
117        int ret = 0;
118
119        if (!res)
120                return -ENOENT;
121        res = devm_request_mem_region(&pdev->dev, res->start,
122                resource_size(res), dev_name(&pdev->dev));
123        if (!res) {
124                dev_err(&pdev->dev, "failed to request STP memory\n");
125                return -EBUSY;
126        }
127        ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
128                resource_size(res));
129        if (!ltq_stp_membase) {
130                dev_err(&pdev->dev, "failed to remap STP memory\n");
131                return -ENOMEM;
132        }
133        ret = gpiochip_add(&ltq_stp_chip);
134        if (!ret)
135                ret = ltq_stp_hw_init();
136
137        return ret;
138}
139
140static struct platform_driver ltq_stp_driver = {
141        .probe = ltq_stp_probe,
142        .driver = {
143                .name = "ltq_stp",
144                .owner = THIS_MODULE,
145        },
146};
147
148int __init ltq_stp_init(void)
149{
150        int ret = platform_driver_register(&ltq_stp_driver);
151
152        if (ret)
153                pr_info("ltq_stp: error registering platfom driver");
154        return ret;
155}
156
157postcore_initcall(ltq_stp_init);
Note: See TracBrowser for help on using the repository browser.