2678876ba45c986102a07863d37a70b1992a73e4
[openwrt.git] / target / linux / ar7 / patches-2.6.32 / 930-titan-platform.patch
1 --- a/arch/mips/ar7/platform.c
2 +++ b/arch/mips/ar7/platform.c
3 @@ -131,6 +131,36 @@ static struct resource cpmac_high_res[]
4         },
5  };
6  
7 +static struct resource cpmac_low_res_titan[] = {
8 +       {
9 +               .name = "regs",
10 +               .flags = IORESOURCE_MEM,
11 +               .start = TITAN_REGS_MAC0,
12 +               .end = TITAN_REGS_MAC0 + 0x7ff,
13 +       },
14 +       {
15 +               .name = "irq",
16 +               .flags = IORESOURCE_IRQ,
17 +               .start = 27,
18 +               .end = 27,
19 +       },
20 +};
21 +
22 +static struct resource cpmac_high_res_titan[] = {
23 +       {
24 +               .name = "regs",
25 +               .flags = IORESOURCE_MEM,
26 +               .start = TITAN_REGS_MAC1,
27 +               .end = TITAN_REGS_MAC1 + 0x7ff,
28 +       },
29 +       {
30 +               .name = "irq",
31 +               .flags = IORESOURCE_IRQ,
32 +               .start = 41,
33 +               .end = 41,
34 +       },
35 +};
36 +
37  static struct resource vlynq_low_res[] = {
38         {
39                 .name = "regs",
40 @@ -185,6 +215,60 @@ static struct resource vlynq_high_res[]
41         },
42  };
43  
44 +static struct resource vlynq_low_res_titan[] = {
45 +       {
46 +               .name = "regs",
47 +               .flags = IORESOURCE_MEM,
48 +               .start = TITAN_REGS_VLYNQ0,
49 +               .end = TITAN_REGS_VLYNQ0 + 0xff,
50 +       },
51 +       {
52 +               .name = "irq",
53 +               .flags = IORESOURCE_IRQ,
54 +               .start = 33,
55 +               .end = 33,
56 +       },
57 +       {
58 +               .name = "mem",
59 +               .flags = IORESOURCE_MEM,
60 +               .start = 0x0c000000,
61 +               .end = 0x0fffffff,
62 +       },
63 +       {
64 +               .name = "devirq",
65 +               .flags = IORESOURCE_IRQ,
66 +               .start = 80,
67 +               .end = 111,
68 +       },
69 +};
70 +
71 +static struct resource vlynq_high_res_titan[] = {
72 +       {
73 +               .name = "regs",
74 +               .flags = IORESOURCE_MEM,
75 +               .start = TITAN_REGS_VLYNQ1,
76 +               .end = TITAN_REGS_VLYNQ1 + 0xff,
77 +       },
78 +       {
79 +               .name = "irq",
80 +               .flags = IORESOURCE_IRQ,
81 +               .start = 34,
82 +               .end = 34,
83 +       },
84 +       {
85 +               .name = "mem",
86 +               .flags = IORESOURCE_MEM,
87 +               .start = 0x40000000,
88 +               .end = 0x43ffffff,
89 +       },
90 +       {
91 +               .name = "devirq",
92 +               .flags = IORESOURCE_IRQ,
93 +               .start = 112,
94 +               .end = 143,
95 +       },
96 +};
97 +
98  static struct resource usb_res[] = {
99         {
100                 .name = "regs",
101 @@ -228,6 +312,18 @@ static struct plat_cpmac_data cpmac_high
102         .phy_mask = 0x7fffffff,
103  };
104  
105 +static struct plat_cpmac_data cpmac_low_data_titan = {
106 +       .reset_bit = 17,
107 +       .power_bit = 20,
108 +       .phy_mask = 0x40000000,
109 +};
110 +
111 +static struct plat_cpmac_data cpmac_high_data_titan = {
112 +       .reset_bit = 21,
113 +       .power_bit = 22,
114 +       .phy_mask = 0x80000000,
115 +};
116 +
117  static struct plat_vlynq_data vlynq_low_data = {
118         .ops.on = vlynq_on,
119         .ops.off = vlynq_off,
120 @@ -242,6 +338,20 @@ static struct plat_vlynq_data vlynq_high
121         .gpio_bit = 19,
122  };
123  
124 +static struct plat_vlynq_data vlynq_low_data_titan = {
125 +       .ops.on = vlynq_on,
126 +       .ops.off = vlynq_off,
127 +       .reset_bit = 15,
128 +       .gpio_bit = 14,
129 +};
130 +
131 +static struct plat_vlynq_data vlynq_high_data_titan = {
132 +       .ops.on = vlynq_on,
133 +       .ops.off = vlynq_off,
134 +       .reset_bit = 16,
135 +       .gpio_bit = 7,
136 +};
137 +
138  static struct platform_device physmap_flash = {
139         .id = 0,
140         .name = "physmap-flash",
141 @@ -275,6 +385,30 @@ static struct platform_device cpmac_high
142         .num_resources = ARRAY_SIZE(cpmac_high_res),
143  };
144  
145 +static struct platform_device cpmac_low_titan = {
146 +       .id = 0,
147 +       .name = "cpmac",
148 +       .dev = {
149 +               .dma_mask = &cpmac_dma_mask,
150 +               .coherent_dma_mask = DMA_BIT_MASK(32),
151 +               .platform_data = &cpmac_low_data_titan,
152 +       },
153 +       .resource = cpmac_low_res_titan,
154 +       .num_resources = ARRAY_SIZE(cpmac_low_res_titan),
155 +};
156 +
157 +static struct platform_device cpmac_high_titan = {
158 +       .id = 1,
159 +       .name = "cpmac",
160 +       .dev = {
161 +               .dma_mask = &cpmac_dma_mask,
162 +               .coherent_dma_mask = DMA_BIT_MASK(32),
163 +               .platform_data = &cpmac_high_data_titan,
164 +       },
165 +       .resource = cpmac_high_res_titan,
166 +       .num_resources = ARRAY_SIZE(cpmac_high_res_titan),
167 +};
168 +
169  static struct platform_device vlynq_low = {
170         .id = 0,
171         .name = "vlynq",
172 @@ -291,6 +425,22 @@ static struct platform_device vlynq_high
173         .num_resources = ARRAY_SIZE(vlynq_high_res),
174  };
175  
176 +static struct platform_device vlynq_low_titan = {
177 +       .id = 0,
178 +       .name = "vlynq",
179 +       .dev.platform_data = &vlynq_low_data_titan,
180 +       .resource = vlynq_low_res_titan,
181 +       .num_resources = ARRAY_SIZE(vlynq_low_res_titan),
182 +};
183 +
184 +static struct platform_device vlynq_high_titan = {
185 +       .id = 1,
186 +       .name = "vlynq",
187 +       .dev.platform_data = &vlynq_high_data_titan,
188 +       .resource = vlynq_high_res_titan,
189 +       .num_resources = ARRAY_SIZE(vlynq_high_res_titan),
190 +};
191 +
192  
193  static struct gpio_led default_leds[] = {
194         {
195 @@ -300,6 +450,11 @@ static struct gpio_led default_leds[] =
196         },
197  };
198  
199 +static struct gpio_led titan_leds[] = {
200 +       { .name = "status", .gpio = 8, .active_low = 1, },
201 +       { .name = "wifi", .gpio = 13, .active_low = 1, },
202 +};
203 +
204  static struct gpio_led dsl502t_leds[] = {
205         {
206                 .name = "status",
207 @@ -496,6 +651,9 @@ static void __init detect_leds(void)
208         } else if (strstr(prid, "DG834")) {
209                 ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
210                 ar7_led_data.leds = dg834g_leds;
211 +       } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
212 +               ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
213 +               ar7_led_data.leds = titan_leds;
214         }
215  }
216  
217 @@ -541,14 +699,18 @@ static int __init ar7_register_devices(v
218         if (res)
219                 return res;
220  
221 -       ar7_device_disable(vlynq_low_data.reset_bit);
222 -       res = platform_device_register(&vlynq_low);
223 +       ar7_device_disable(ar7_is_titan() ? vlynq_low_data_titan.reset_bit :
224 +               vlynq_low_data.reset_bit);
225 +       res = platform_device_register(ar7_is_titan() ? &vlynq_low_titan :
226 +               &vlynq_low);
227         if (res)
228                 return res;
229  
230         if (ar7_has_high_vlynq()) {
231 -               ar7_device_disable(vlynq_high_data.reset_bit);
232 -               res = platform_device_register(&vlynq_high);
233 +               ar7_device_disable(ar7_is_titan() ? vlynq_high_data_titan.reset_bit :
234 +                       vlynq_high_data.reset_bit);
235 +               res = platform_device_register(ar7_is_titan() ? &vlynq_high_titan :
236 +                       &vlynq_high);
237                 if (res)
238                         return res;
239         }
240 --- a/arch/mips/ar7/gpio.c
241 +++ b/arch/mips/ar7/gpio.c
242 @@ -21,11 +21,11 @@
243  
244  #include <asm/mach-ar7/gpio.h>
245  
246 -static const char *ar7_gpio_list[AR7_GPIO_MAX];
247 +static const char *ar7_gpio_list[TITAN_GPIO_MAX];
248  
249  int gpio_request(unsigned gpio, const char *label)
250  {
251 -       if (gpio >= AR7_GPIO_MAX)
252 +       if (gpio >= (ar7_is_titan() ? TITAN_GPIO_MAX : AR7_GPIO_MAX))
253                 return -EINVAL;
254  
255         if (ar7_gpio_list[gpio])
256 --- a/arch/mips/ar7/setup.c
257 +++ b/arch/mips/ar7/setup.c
258 @@ -23,6 +23,9 @@
259  #include <asm/reboot.h>
260  #include <asm/mach-ar7/ar7.h>
261  #include <asm/mach-ar7/prom.h>
262 +#include <asm/mach-ar7/gpio.h>
263 +
264 +static int titan_variant;
265  
266  static void ar7_machine_restart(char *command)
267  {
268 @@ -55,6 +58,18 @@ const char *get_system_type(void)
269                 return "TI AR7 (TNETD7100)";
270         case AR7_CHIP_7200:
271                 return "TI AR7 (TNETD7200)";
272 +       case AR7_CHIP_TITAN:
273 +               titan_variant = ar7_init_titan_variant();
274 +               switch (titan_variant /*(gpio_get_value_titan(1) >> 12) & 0xf*/) {
275 +               case TITAN_CHIP_1050:
276 +                       return "TI AR7 (TNETV1050)";
277 +               case TITAN_CHIP_1055:
278 +                       return "TI AR7 (TNETV1055)";
279 +               case TITAN_CHIP_1056:
280 +                       return "TI AR7 (TNETV1056)";
281 +               case TITAN_CHIP_1060:
282 +                       return "TI AR7 (TNETV1060)";
283 +               }
284         default:
285                 return "TI AR7 (Unknown)";
286         }
287 --- a/arch/mips/include/asm/mach-ar7/ar7.h
288 +++ b/arch/mips/include/asm/mach-ar7/ar7.h
289 @@ -50,6 +50,11 @@
290  #define UR8_REGS_WDT   (AR7_REGS_BASE + 0x0b00)
291  #define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
292  
293 +#define TITAN_REGS_MAC0                (0x08640000)
294 +#define TITAN_REGS_MAC1                (TITAN_REGS_MAC0 + 0x0800)
295 +#define TITAN_REGS_VLYNQ0      (AR7_REGS_BASE + 0x1c00)
296 +#define TITAN_REGS_VLYNQ1      (AR7_REGS_BASE + 0x1300)
297 +
298  #define AR7_RESET_PEREPHERIAL  0x0
299  #define AR7_RESET_SOFTWARE     0x4
300  #define AR7_RESET_STATUS       0x8
301 @@ -59,15 +64,30 @@
302  #define AR7_RESET_BIT_MDIO     22
303  #define AR7_RESET_BIT_EPHY     26
304  
305 +#define TITAN_RESET_BIT_EPHY1  28
306 +
307  /* GPIO control registers */
308  #define AR7_GPIO_INPUT 0x0
309  #define AR7_GPIO_OUTPUT        0x4
310  #define AR7_GPIO_DIR   0x8
311  #define AR7_GPIO_ENABLE        0xc
312 +#define TITAN_GPIO_INPUT_0     0x0
313 +#define TITAN_GPIO_INPUT_1     0x4
314 +#define TITAN_GPIO_OUTPUT_0    0x8
315 +#define TITAN_GPIO_OUTPUT_1    0xc
316 +#define TITAN_GPIO_DIR_0       0x10
317 +#define TITAN_GPIO_DIR_1       0x14
318 +#define TITAN_GPIO_ENBL_0      0x18
319 +#define TITAN_GPIO_ENBL_1      0x1c
320  
321  #define AR7_CHIP_7100  0x18
322  #define AR7_CHIP_7200  0x2b
323  #define AR7_CHIP_7300  0x05
324 +#define AR7_CHIP_TITAN 0x07
325 +#define TITAN_CHIP_1050        0x0f
326 +#define TITAN_CHIP_1055        0x0e
327 +#define TITAN_CHIP_1056        0x0d
328 +#define TITAN_CHIP_1060        0x07
329  
330  /* Interrupts */
331  #define AR7_IRQ_UART0  15
332 @@ -95,14 +115,22 @@ struct plat_dsl_data {
333  
334  extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
335  
336 +static inline int ar7_is_titan(void)
337 +{
338 +       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
339 +               AR7_CHIP_TITAN;
340 +}
341 +
342  static inline u16 ar7_chip_id(void)
343  {
344 -       return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
345 +       return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
346 +               KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
347  }
348  
349  static inline u8 ar7_chip_rev(void)
350  {
351 -       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
352 +       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
353 +               0x14))) >> 16) & 0xff;
354  }
355  
356  static inline int ar7_cpu_freq(void)
357 --- a/arch/mips/include/asm/mach-ar7/gpio.h
358 +++ b/arch/mips/include/asm/mach-ar7/gpio.h
359 @@ -20,14 +20,18 @@
360  #define __AR7_GPIO_H__
361  
362  #include <asm/mach-ar7/ar7.h>
363 +#ifndef __AR7_TITAN_H__
364 +#include <asm/mach-ar7/titan.h>
365 +#endif
366  
367  #define AR7_GPIO_MAX 32
368 +#define TITAN_GPIO_MAX 51
369  
370  extern int gpio_request(unsigned gpio, const char *label);
371  extern void gpio_free(unsigned gpio);
372  
373  /* Common GPIO layer */
374 -static inline int gpio_get_value(unsigned gpio)
375 +static inline int gpio_get_value_ar7(unsigned gpio)
376  {
377         void __iomem *gpio_in =
378                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_INPUT);
379 @@ -35,7 +39,23 @@ static inline int gpio_get_value(unsigne
380         return readl(gpio_in) & (1 << gpio);
381  }
382  
383 -static inline void gpio_set_value(unsigned gpio, int value)
384 +static inline int gpio_get_value_titan(unsigned gpio)
385 +{
386 +       void __iomem *gpio_in0 =
387 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_INPUT_0);
388 +       void __iomem *gpio_in1 =
389 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_INPUT_1);
390 +
391 +       return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
392 +}
393 +
394 +static inline int gpio_get_value(unsigned gpio)
395 +{
396 +       return ar7_is_titan() ? gpio_get_value_titan(gpio) :
397 +               gpio_get_value_ar7(gpio);
398 +}
399 +
400 +static inline void gpio_set_value_ar7(unsigned gpio, int value)
401  {
402         void __iomem *gpio_out =
403                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_OUTPUT);
404 @@ -47,7 +67,29 @@ static inline void gpio_set_value(unsign
405         writel(tmp, gpio_out);
406  }
407  
408 -static inline int gpio_direction_input(unsigned gpio)
409 +static inline void gpio_set_value_titan(unsigned gpio, int value)
410 +{
411 +       void __iomem *gpio_out0 =
412 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_OUTPUT_0);
413 +       void __iomem *gpio_out1 =
414 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_OUTPUT_1);
415 +       unsigned tmp;
416 +
417 +       tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
418 +       if (value)
419 +               tmp |= 1 << (gpio & 0x1f);
420 +       writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
421 +}
422 +
423 +static inline void gpio_set_value(unsigned gpio, int value)
424 +{
425 +       if (ar7_is_titan())
426 +               gpio_set_value_titan(gpio, value);
427 +       else
428 +               gpio_set_value_ar7(gpio, value);
429 +}
430 +
431 +static inline int gpio_direction_input_ar7(unsigned gpio)
432  {
433         void __iomem *gpio_dir =
434                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
435 @@ -60,7 +102,29 @@ static inline int gpio_direction_input(u
436         return 0;
437  }
438  
439 -static inline int gpio_direction_output(unsigned gpio, int value)
440 +static inline int gpio_direction_input_titan(unsigned gpio)
441 +{
442 +       void __iomem *gpio_dir0 =
443 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_DIR_0);
444 +       void __iomem *gpio_dir1 =
445 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_DIR_1);
446 +
447 +       if (gpio >= TITAN_GPIO_MAX)
448 +               return -EINVAL;
449 +
450 +       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
451 +               gpio >> 5 ? gpio_dir1 : gpio_dir0);
452 +
453 +       return 0;
454 +}
455 +
456 +static inline int gpio_direction_input(unsigned gpio)
457 +{
458 +       return ar7_is_titan() ?  gpio_direction_input_titan(gpio) :
459 +               gpio_direction_input_ar7(gpio);
460 +}
461 +
462 +static inline int gpio_direction_output_ar7(unsigned gpio, int value)
463  {
464         void __iomem *gpio_dir =
465                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
466 @@ -74,6 +138,29 @@ static inline int gpio_direction_output(
467         return 0;
468  }
469  
470 +static inline int gpio_direction_output_titan(unsigned gpio, int value)
471 +{
472 +       void __iomem *gpio_dir0 =
473 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_DIR_0);
474 +       void __iomem *gpio_dir1 =
475 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_DIR_1);
476 +
477 +       if (gpio >= TITAN_GPIO_MAX)
478 +               return -EINVAL;
479 +
480 +       gpio_set_value_titan(gpio, value);
481 +       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
482 +               (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
483 +
484 +       return 0;
485 +}
486 +
487 +static inline int gpio_direction_output(unsigned gpio, int value)
488 +{
489 +       return ar7_is_titan() ?  gpio_direction_output_titan(gpio, value) :
490 +               gpio_direction_output_ar7(gpio, value);
491 +}
492 +
493  static inline int gpio_to_irq(unsigned gpio)
494  {
495         return -EINVAL;
496 @@ -85,7 +172,7 @@ static inline int irq_to_gpio(unsigned i
497  }
498  
499  /* Board specific GPIO functions */
500 -static inline int ar7_gpio_enable(unsigned gpio)
501 +static inline int ar7_gpio_enable_ar7(unsigned gpio)
502  {
503         void __iomem *gpio_en =
504                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
505 @@ -95,7 +182,26 @@ static inline int ar7_gpio_enable(unsign
506         return 0;
507  }
508  
509 -static inline int ar7_gpio_disable(unsigned gpio)
510 +static inline int ar7_gpio_enable_titan(unsigned gpio)
511 +{
512 +       void __iomem *gpio_en0 =
513 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_ENBL_0);
514 +       void __iomem *gpio_en1 =
515 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_ENBL_1);
516 +
517 +       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
518 +               gpio >> 5 ? gpio_en1 : gpio_en0);
519 +
520 +       return 0;
521 +}
522 +
523 +static inline int ar7_gpio_enable(unsigned gpio)
524 +{
525 +       return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
526 +               ar7_gpio_enable_ar7(gpio);
527 +}
528 +
529 +static inline int ar7_gpio_disable_ar7(unsigned gpio)
530  {
531         void __iomem *gpio_en =
532                 (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
533 @@ -105,6 +211,60 @@ static inline int ar7_gpio_disable(unsig
534         return 0;
535  }
536  
537 +static inline int ar7_gpio_disable_titan(unsigned gpio)
538 +{
539 +       void __iomem *gpio_en0 =
540 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_ENBL_0);
541 +       void __iomem *gpio_en1 =
542 +               (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_ENBL_1);
543 +
544 +       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
545 +               gpio >> 5 ? gpio_en1 : gpio_en0);
546 +
547 +       return 0;
548 +}
549 +
550 +static inline int ar7_gpio_disable(unsigned gpio)
551 +{
552 +       return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
553 +               ar7_gpio_disable_ar7(gpio);
554 +}
555 +
556 +static inline int ar7_init_titan_variant(void)
557 +{
558 +       /*UINT32 new_val;*/
559 +       unsigned new_val;
560 +
561 +       /* set GPIO 44 - 47 as input */
562 +       /*PAL_sysGpioCtrl(const int, GPIO_PIN, GPIO_INPUT_PIN); */
563 +       /*define titan_gpio_ctrl in titan.h*/
564 +       titan_gpio_ctrl(44, GPIO_PIN, GPIO_INPUT_PIN);
565 +       titan_gpio_ctrl(45, GPIO_PIN, GPIO_INPUT_PIN);
566 +       titan_gpio_ctrl(46, GPIO_PIN, GPIO_INPUT_PIN);
567 +       titan_gpio_ctrl(47, GPIO_PIN, GPIO_INPUT_PIN);
568 +
569 +       /* read GPIO to get Titan variant type */
570 +       /*fix this*/
571 +       titan_sysGpioInValue( &new_val, 1 );
572 +
573 +       new_val >>= 12;
574 +       new_val &= 0x0f;
575 +
576 +       switch ( new_val )
577 +       {
578 +       case TITAN_CHIP_1050:
579 +       case TITAN_CHIP_1055:
580 +       case TITAN_CHIP_1056:
581 +       case TITAN_CHIP_1060:
582 +               return new_val;
583 +
584 +       default:
585 +               break;
586 +       }
587 +       /* In case we get an invalid value, return the default Titan chip */
588 +       return TITAN_CHIP_1050;
589 +}
590 +
591  #include <asm-generic/gpio.h>
592  
593  #endif
594 --- /dev/null
595 +++ b/arch/mips/include/asm/mach-ar7/titan.h
596 @@ -0,0 +1,176 @@
597 +/*
598 + * Copyright (C) 2008 Stanley Pinchak <stanley_dot_pinchak_at_gmail_dot_com>
599 + *
600 + * This program is free software; you can redistribute it and/or modify
601 + * it under the terms of the GNU General Public License as published by
602 + * the Free Software Foundation; either version 2 of the License, or
603 + * (at your option) any later version.
604 + *
605 + * This program is distributed in the hope that it will be useful,
606 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
607 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
608 + * GNU General Public License for more details.
609 + *
610 + * You should have received a copy of the GNU General Public License
611 + * along with this program; if not, write to the Free Software
612 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
613 + */
614 +#ifndef __AR7_TITAN_H__
615 +#define __AR7_TITAN_H__
616 +
617 +#include <asm/mach-ar7/gpio.h>
618 +
619 +typedef enum TITAN_GPIO_PIN_MODE_tag
620 +{
621 +    FUNCTIONAL_PIN = 0,
622 +    GPIO_PIN = 1
623 +} TITAN_GPIO_PIN_MODE_T;
624 +
625 +typedef enum TITAN_GPIO_PIN_DIRECTION_tag
626 +{
627 +    GPIO_OUTPUT_PIN = 0,
628 +    GPIO_INPUT_PIN = 1
629 +} TITAN_GPIO_PIN_DIRECTION_T;
630 +
631 +/**********************************************************************
632 + *  GPIO Control
633 + **********************************************************************/
634 +
635 +typedef struct 
636 +{
637 +    int pinSelReg;
638 +    int shift;
639 +    int func;
640 +
641 +} GPIO_CFG;
642 +
643 +static GPIO_CFG gptable[]= {
644 +                     /* PIN_SEL_REG, START_BIT, GPIO_CFG_MUX_VALUE */
645 +                     {4,24,1},
646 +                     {4,26,1},
647 +                     {4,28,1},
648 +                     {4,30,1},
649 +                     {5,6,1},
650 +                     {5,8,1},
651 +                     {5,10,1},
652 +                     {5,12,1},
653 +                     {7,14,3},
654 +                     {7,16,3},
655 +                     {7,18,3},
656 +                     {7,20,3},
657 +                     {7,22,3},
658 +                     {7,26,3},
659 +                     {7,28,3},
660 +                     {7,30,3},
661 +                      {8,0,3},
662 +                     {8,2,3},
663 +                     {8,4,3},
664 +                     {8,10,3},
665 +                     {8,14,3},
666 +                     {8,16,3},
667 +                     {8,18,3},
668 +                     {8,20,3},
669 +                     {9,8,3},
670 +                     {9,10,3},
671 +                     {9,12,3},
672 +                     {9,14,3},
673 +                     {9,18,3},
674 +                     {9,20,3},
675 +                     {9,24,3},
676 +                     {9,26,3},
677 +                     {9,28,3},
678 +                     {9,30,3},
679 +                     {10,0,3},
680 +                     {10,2,3},
681 +                     {10,8,3},
682 +                     {10,10,3},
683 +                     {10,12,3},
684 +                     {10,14,3},
685 +                     {13,12,3},
686 +                     {13,14,3},
687 +                     {13,16,3},
688 +                     {13,18,3},
689 +                     {13,24,3},
690 +                     {13,26,3},
691 +                     {13,28,3},
692 +                     {13,30,3},
693 +                     {14,2,3},
694 +                     {14,6,3},
695 +                     {14,8,3},
696 +                     {14,12,3}
697 +};
698 +
699 +typedef struct
700 +{
701 +    volatile unsigned int reg[21];
702 +}
703 +PIN_SEL_REG_ARRAY_T;
704 +
705 +typedef struct
706 +{
707 +    unsigned int data_in [2];
708 +    unsigned int data_out[2];
709 +    unsigned int dir[2];
710 +    unsigned int enable[2];
711 +
712 +} TITAN_GPIO_CONTROL_T;
713 +
714 +#define AVALANCHE_PIN_SEL_BASE        0xA861160C /*replace with KSEG1ADDR()*/
715 +
716 +static inline int titan_gpio_ctrl(unsigned int gpio_pin, TITAN_GPIO_PIN_MODE_T pin_mode,
717 +                        TITAN_GPIO_PIN_DIRECTION_T pin_direction)
718 +{
719 +    int reg_index = 0;
720 +    int mux_status;
721 +    GPIO_CFG  gpio_cfg;
722 +    volatile PIN_SEL_REG_ARRAY_T *pin_sel_array = (PIN_SEL_REG_ARRAY_T*) AVALANCHE_PIN_SEL_BASE;
723 +    volatile TITAN_GPIO_CONTROL_T   *gpio_cntl     = (TITAN_GPIO_CONTROL_T*) KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_INPUT_0);
724 +       
725 +    if (gpio_pin > 51 )
726 +        return(-1);
727 +
728 +    gpio_cfg = gptable[gpio_pin];
729 +    mux_status = (pin_sel_array->reg[gpio_cfg.pinSelReg - 1] >> gpio_cfg.shift) & 0x3;
730 +    if(!((mux_status == 0 /* tri-stated */ ) || (mux_status == gpio_cfg.func /*GPIO functionality*/)))
731 +    {
732 +        return(-1); /* Pin have been configured for non GPIO funcs. */
733 +    }
734 +
735 +    /* Set the pin to be used as GPIO. */
736 +    pin_sel_array->reg[gpio_cfg.pinSelReg - 1] |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
737 +
738 +    /* Check whether gpio refers to the first GPIO reg or second. */
739 +    if(gpio_pin > 31)
740 +    {
741 +       reg_index = 1;
742 +       gpio_pin -= 32;
743 +    }
744 +
745 +    if(pin_mode)
746 +        gpio_cntl->enable[reg_index] |=  (1 << gpio_pin); /* Enable */
747 +    else
748 +       gpio_cntl->enable[reg_index] &= ~(1 << gpio_pin);
749 +
750 +    if(pin_direction)
751 +        gpio_cntl->dir[reg_index] |=  (1 << gpio_pin); /* Input */
752 +    else
753 +       gpio_cntl->dir[reg_index] &= ~(1 << gpio_pin);
754 +
755 +    return(0);
756 +
757 +}/* end of function titan_gpio_ctrl */
758 +
759 +static inline int titan_sysGpioInValue(unsigned int *in_val, unsigned int reg_index)
760 +{
761 +    volatile TITAN_GPIO_CONTROL_T   *gpio_cntl     = (TITAN_GPIO_CONTROL_T*) KSEG1ADDR(AR7_REGS_GPIO + TITAN_GPIO_INPUT_0);
762 +
763 +    if(reg_index > 1)
764 +       return (-1);
765 +
766 +    *in_val = gpio_cntl->data_in[reg_index];
767 +
768 +    return (0);
769 +}
770 +
771 +
772 +#endif