1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/arch/sh/boards/hp6xx/setup.c |
4 | * |
5 | * Copyright (C) 2002 Andriy Skulysh |
6 | * Copyright (C) 2007 Kristoffer Ericson <Kristoffer_e1@hotmail.com> |
7 | * |
8 | * Setup code for HP620/HP660/HP680/HP690 (internal peripherials only) |
9 | */ |
10 | #include <linux/types.h> |
11 | #include <linux/init.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/irq.h> |
14 | #include <linux/sh_intc.h> |
15 | #include <sound/sh_dac_audio.h> |
16 | #include <asm/hd64461.h> |
17 | #include <asm/io.h> |
18 | #include <mach/hp6xx.h> |
19 | #include <cpu/dac.h> |
20 | |
21 | #define SCPCR 0xa4000116 |
22 | #define SCPDR 0xa4000136 |
23 | |
24 | /* CF Slot */ |
25 | static struct resource cf_ide_resources[] = { |
26 | [0] = { |
27 | .start = 0x15000000 + 0x1f0, |
28 | .end = 0x15000000 + 0x1f0 + 0x08 - 0x01, |
29 | .flags = IORESOURCE_MEM, |
30 | }, |
31 | [1] = { |
32 | .start = 0x15000000 + 0x1fe, |
33 | .end = 0x15000000 + 0x1fe + 0x01, |
34 | .flags = IORESOURCE_MEM, |
35 | }, |
36 | [2] = { |
37 | .start = evt2irq(0xba0), |
38 | .flags = IORESOURCE_IRQ, |
39 | }, |
40 | }; |
41 | |
42 | static struct platform_device cf_ide_device = { |
43 | .name = "pata_platform" , |
44 | .id = -1, |
45 | .num_resources = ARRAY_SIZE(cf_ide_resources), |
46 | .resource = cf_ide_resources, |
47 | }; |
48 | |
49 | static struct platform_device jornadakbd_device = { |
50 | .name = "jornada680_kbd" , |
51 | .id = -1, |
52 | }; |
53 | |
54 | static void dac_audio_start(struct dac_audio_pdata *pdata) |
55 | { |
56 | u16 v; |
57 | u8 v8; |
58 | |
59 | /* HP Jornada 680/690 speaker on */ |
60 | v = inw(port: HD64461_GPADR); |
61 | v &= ~HD64461_GPADR_SPEAKER; |
62 | outw(value: v, port: HD64461_GPADR); |
63 | |
64 | /* HP Palmtop 620lx/660lx speaker on */ |
65 | v8 = inb(port: PKDR); |
66 | v8 &= ~PKDR_SPEAKER; |
67 | outb(value: v8, port: PKDR); |
68 | |
69 | sh_dac_enable(pdata->channel); |
70 | } |
71 | |
72 | static void dac_audio_stop(struct dac_audio_pdata *pdata) |
73 | { |
74 | u16 v; |
75 | u8 v8; |
76 | |
77 | /* HP Jornada 680/690 speaker off */ |
78 | v = inw(port: HD64461_GPADR); |
79 | v |= HD64461_GPADR_SPEAKER; |
80 | outw(value: v, port: HD64461_GPADR); |
81 | |
82 | /* HP Palmtop 620lx/660lx speaker off */ |
83 | v8 = inb(port: PKDR); |
84 | v8 |= PKDR_SPEAKER; |
85 | outb(value: v8, port: PKDR); |
86 | |
87 | sh_dac_output(0, pdata->channel); |
88 | sh_dac_disable(pdata->channel); |
89 | } |
90 | |
91 | static struct dac_audio_pdata dac_audio_platform_data = { |
92 | .buffer_size = 64000, |
93 | .channel = 1, |
94 | .start = dac_audio_start, |
95 | .stop = dac_audio_stop, |
96 | }; |
97 | |
98 | static struct platform_device dac_audio_device = { |
99 | .name = "dac_audio" , |
100 | .id = -1, |
101 | .dev = { |
102 | .platform_data = &dac_audio_platform_data, |
103 | } |
104 | |
105 | }; |
106 | |
107 | static struct platform_device *hp6xx_devices[] __initdata = { |
108 | &cf_ide_device, |
109 | &jornadakbd_device, |
110 | &dac_audio_device, |
111 | }; |
112 | |
113 | static void __init hp6xx_init_irq(void) |
114 | { |
115 | /* Gets touchscreen and powerbutton IRQ working */ |
116 | plat_irq_setup_pins(IRQ_MODE_IRQ); |
117 | } |
118 | |
119 | static int __init hp6xx_devices_setup(void) |
120 | { |
121 | return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); |
122 | } |
123 | |
124 | static void __init hp6xx_setup(char **cmdline_p) |
125 | { |
126 | u8 v8; |
127 | u16 v; |
128 | |
129 | v = inw(port: HD64461_STBCR); |
130 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | |
131 | HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | |
132 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | |
133 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST| |
134 | HD64461_STBCR_SAFECKE_IST; |
135 | #ifndef CONFIG_HD64461_ENABLER |
136 | v |= HD64461_STBCR_SPC1ST; |
137 | #endif |
138 | outw(value: v, port: HD64461_STBCR); |
139 | v = inw(port: HD64461_GPADR); |
140 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; |
141 | outw(value: v, port: HD64461_GPADR); |
142 | |
143 | outw(value: HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, port: HD64461_PCC0GCR); |
144 | |
145 | #ifndef CONFIG_HD64461_ENABLER |
146 | outw(value: HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, port: HD64461_PCC1GCR); |
147 | #endif |
148 | |
149 | sh_dac_output(0, DAC_SPEAKER_VOLUME); |
150 | sh_dac_disable(DAC_SPEAKER_VOLUME); |
151 | v8 = __raw_readb(addr: DACR); |
152 | v8 &= ~DACR_DAE; |
153 | __raw_writeb(val: v8,addr: DACR); |
154 | |
155 | v8 = __raw_readb(SCPDR); |
156 | v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y; |
157 | v8 &= ~SCPDR_TS_SCAN_ENABLE; |
158 | __raw_writeb(val: v8, SCPDR); |
159 | |
160 | v = __raw_readw(SCPCR); |
161 | v &= ~SCPCR_TS_MASK; |
162 | v |= SCPCR_TS_ENABLE; |
163 | __raw_writew(val: v, SCPCR); |
164 | } |
165 | device_initcall(hp6xx_devices_setup); |
166 | |
167 | static struct sh_machine_vector mv_hp6xx __initmv = { |
168 | .mv_name = "hp6xx" , |
169 | .mv_setup = hp6xx_setup, |
170 | /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ |
171 | .mv_init_irq = hp6xx_init_irq, |
172 | }; |
173 | |